Entity framework - Invalid Object Name - entity-framework

I have a project where i use EF 4.1.
At Data Context:
public DbSet<Customer> Customer { get; set; }
protected override void OnModelCreating(System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder) { }
Entity model class:
[Table("User",SchemaName="dbo")]
public class User{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
Once I run the application I was getting following error.
Invalid object name dbo.User
Why? What is wrong?

What is in your OnModelCreating method?
Try to remove default plural table name:
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();

If you happen to be using configuration mapping (EntityTypeConfiguration) classes to define your tables, you'll get this error if you forget to attach the Configuration class for the table to the Model Builder.
In my case, it really stumped me for a bit, because I already had another table (SomeThing) working perfectly within this Context class. After simply adding a new table (OtherThing) where everything seemed to be setup identical to the first, I got the error: Invalid object name 'dbo.OtherThings.
The answer was in my Context class:
public DbSet<SomeThing> SomeThings { get; set; }
public DbSet<OtherThing> OtherThings { get; set; }
...
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new SomeThingMap());
// OOPS -- Forgot to add this!!
modelBuilder.Configurations.Add(new OtherThingMap());
}
For reference, here's my SomeThingMap class:
public class SomeThingMap : EntityTypeConfiguration<SomeThing>
{
public SomeThingMap()
{
...
this.ToTable("SomeThing");
...
}
}
And my new OtherThingMap class:
public class OtherThingMap : EntityTypeConfiguration<OtherThing>
{
public OtherThingMap()
{
...
this.ToTable("OtherThing");
...
}
}
It's a long shot, but I hope this helps point someone else in the right direction, at least.

Related

EF 6 - How to get DbSet by table name

I have a DbContext that looks like this:
public partial class MyDbConnectionConnection : DbContext
{
public MyDbConnectionConnection()
: base("name=MyDbConnectionConnection ")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public DbSet<Name> tbName{ get; set; }
public DbSet<Surname> tbSurname{ get; set; }
public DbSet<Address> tbAddress{ get; set; }
public DbSet<Currency> tbCurrency { get; set; }
}
}
and I need to search through this Context and find data set that matches the table name for example:
public dynamic getCorrectEntity()
{
MyDbConnectionConnection Context = new MyDbConnectionConnection();
var dbset = Context.Set(Type.GetType("tbName"));
return dbset;
}
where "tbName" is name of DbSet.
I cannot get anything!
In this line of code Type.GetType("tbName") it returns value null.
I just need to mentioned that I googled, try all examples I found here in the last couple of hours but nothing helps :(
Does anyone know how to get entity on this way?
P.S. I also try all this using Assembly.GetType(name). It didn't help...

Entity Framework table creation

I have a model which looks like below
public class Employee
{
public int Id { get; set; }
public string Email { get; set; }
public string Forename { get; set; }
}
And I have an configuration file as below
public class EmmployeeConfiguration : EntityTypeConfiguration<Employee>
{
public EmmployeeConfiguration()
{
Property(e => e.Forename).IsRequired();
}
}
And I want it to create a table with Name of HR.Employee (HR being the schema). So, in my DbContext, I added the following.
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Entity<Employee>().ToTable("Employee", schemaName: "HR");
modelBuilder.Configurations.Add(new EmmployeeConfiguration());
//base.OnModelCreating(modelBuilder);
}
I am expecting the database name to be "HR.Employee", but instead when i run "Enable-Migration", it is always trying to create "dbo.Employees".
Can someone point me what I am missing?

Why is EF code first throwing model backing context exception? Using 4.0.3

Heres the exception:
The model backing the 'ScannerContext' context has changed since the
database was created. Consider using Code First Migrations to update
the database (http://go.microsoft.com/fwlink/?LinkId=238269).
I get this everytime I run my application. I cant figure out what it means. I think it means something isn't mapped correctly, but I cant figure out what. I am using the code first model, and I have an existing database that I want totally custom mappings for. Right now, I have everything in my classes named the same as my database to eliminate possible cuases.
The Exception is thrown when I try to .Add() the entity to the context.
The Entity as it is in the Database
The Entity in my DataLayer
public class EAsset
{
public int i_GID { get; set; }
public EAssetType Type { get; set; }
public EOrgEnvironment Environment { get; set; }
public EUser Contact { get; set; }
public string s_Name { get; set; }
public string s_Role { get; set; }
public DateTime d_Added { get; set; }
public DateTime d_LastUpdated { get; set; }
public bool b_Retired { get; set; }
public EAsset()
{
Type = new EAssetType();
Environment = new EOrgEnvironment();
Contact = new EUser();
d_Added = DateTime.Now;
d_LastUpdated = DateTime.Now;
}
}
The Context Object (with attempted table mapping and key assignment)
public class ScannerContext : DbContext
{
public ScannerContext()
: base("LabDatabase") { }
public DbSet<EAsset> EAssets { get; set; }
public DbSet<EAssetType> EAssetTypes { get; set; }
public DbSet<EOrgEnvironment> EOrgEnvironments { get; set; }
public DbSet<EUser> EUsers { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<EAsset>().HasKey(k=>k.i_GID).ToTable("t_Assets");
modelBuilder.Entity<EAssetType>().HasKey(k => k.i_ID).ToTable("t_Asset_Types");
modelBuilder.Entity<EOrgEnvironment>().HasKey(k => k.i_ID).ToTable("t_Org_Environments");
modelBuilder.Entity<EUser>().HasKey(k => k.i_ID).ToTable("t_Users");
base.OnModelCreating(modelBuilder);
}
}
The Program
class Program
{
static void Main(string[] args)
{
EAsset Entity = new EAsset { s_Name = "jewri-pc" };
var sContext = new ScannerContext();
sContext.EAssets.Add(Entity);
sContext.SaveChanges();
}
}
For EF runtime version 4.0.3 / version 4.0
public class ScannerContext : DbContext
{
public ScannerContext()
: base("LabDatabase") { }
...
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
Database.SetInitializer<ScannerContext>(null); // <--- This is what i needed
...
base.OnModelCreating(modelBuilder);
}
}
With that code installed I am now chasing errors related to having all my relationships accounted for in the model. The FK Constraints are forcing me to add the missing relational items.
Found info here. They explain the importance a bit.
The model backing the <Database> context has changed since the database was created
Enable-Migrations -ContextTypeName EmployeeProject.Models.DepartmentContext
Means you have to write your project name.Models.Context name
It will work.

in entity framework code first, how to use KeyAttribute on multiple columns

I'm creating a POCO model to use with entity framework code first CTP5. I'm using the decoration to make a property map to a PK column. But how can I define a PK on more then one column, and specifically, how can I control order of the columns in the index? Is it a result of the order of properties in the class?
Thanks!
NOTE:
As of 2019 this answer became non-valid for later EntityFramework versions.
You can specify the column order in the attributes, for instance:
public class MyEntity
{
[Key, Column(Order=0)]
public int MyFirstKeyProperty { get; set; }
[Key, Column(Order=1)]
public int MySecondKeyProperty { get; set; }
[Key, Column(Order=2)]
public string MyThirdKeyProperty { get; set; }
// other properties
}
If you are using the Find method of a DbSet you must take this order for the key parameters into account.
To complete the correct answer submitted by Slauma, you can use the HasKey method to specify an order for composite primary keys as well:
public class User
{
public int UserId { get; set; }
public string Username { get; set; }
}
public class Ctp5Context : DbContext
{
public DbSet<User> Users { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<User>().HasKey(u => new
{
u.UserId,
u.Username
});
}
}
If, like me, you prefer to use a configuration file you can do that in this way (based on Manavi's example):
public class User
{
public int UserId { get; set; }
public string Username { get; set; }
}
public class UserConfiguration : EntityTypeConfiguration<User>
{
public UserConfiguration()
{
ToTable("Users");
HasKey(x => new {x.UserId, x.Username});
}
}
Obviously you have to add the configuration file to your context:
public class Ctp5Context : DbContext
{
public DbSet<User> Users { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new UserConfiguration());
}
}
Use as a anonymous object:
modelBuilder.Entity<UserExamAttemptQuestion>().ToTable("Users").HasKey(o => new { o.UserId, o.Username });

How to map an Entity framework model to a table name dynamically

Using a code-first approach I'd like to map a single model to multiple table names dynamically. Currently I can do something like modelBuilder.Entity(Of Person)().MapSingleType().ToTable("Managers") but as the OnModelCreating method is only called once I can't map it to other table names on the fly.
In our current LinqToSql version we're overriding the MetaModel.GetTable() and returning a new TableAttribute with our dynamic name. I haven't found an attribute like that in EF (even if there were I wouldn't know how to override that yet). So my question is: Is it possible to do this (yet)?
Update
I've found that I can prevent the OnModelCreating method from caching the mappings by calling
modelBuilder.CacheForContextType = false;
As a result I can assign table definitions on instantiation of the object. This isn't quite how I wanted to do it but it works.
Update
Oh boy, was the above a big mistake...Caching exists for a reason! :) So I'm back to square one with POCO object mapping. I'll post an update if I figure out a solution.
Final
Incase anybody cares how I've currently solved this issue, here you go:
First I created a separate library with the POCO tables and an Interface
public interface IDataContext {
System.Data.Entity.DbSet<TableGeneric> TableGeneric { get; set; }
int SaveChanges();
}
public class TableGeneric {
[Key]
public int Column1 { get; set; }
public string Column2 { get; set; }
public DateTime Column3 { get; set; }
public string Column4 { get; set; }
public string Column5 { get; set; }
}
Then, using the CSharpCodeProvider I created a class that takes the following template and turns it into a type definition:
class DataContext : System.Data.Entity.DbContext, IDataContext {
public System.Data.Entity.DbSet<TableGeneric> TableGeneric { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder) {
modelBuilder
.Entity<ContextTesting.Interfaces.EF.TableGeneric()
.MapSingleType()
.ToTable("$TableName$");
}
}
With the generated type I'm able to create an instance so here we go
Type typeAccountants = BuildContext.CreateGenericTable("Accountants");
IDataContext context = (IDataContext)Activator.CreateInstance(typeAccountants);
Then the rest is just as if you had a normal DataContext. Hope this helps someone else.
Incase anybody cares how I've currently solved this issue, here you go:
First I created a separate library with the POCO tables and an Interface
public interface IDataContext {
System.Data.Entity.DbSet<TableGeneric> TableGeneric { get; set; }
int SaveChanges();
}
public class TableGeneric {
[Key]
public int Column1 { get; set; }
public string Column2 { get; set; }
public DateTime Column3 { get; set; }
public string Column4 { get; set; }
public string Column5 { get; set; }
}
Then, using the CSharpCodeProvider I created a class that takes the following template and turns it into a type definition:
class DataContext : System.Data.Entity.DbContext, IDataContext {
public System.Data.Entity.DbSet<TableGeneric> TableGeneric { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder) {
modelBuilder
.Entity<ContextTesting.Interfaces.EF.TableGeneric()
.MapSingleType()
.ToTable("$TableName$");
}
}
With the generated type I'm able to create an instance so here we go
Type typeAccountants = BuildContext.CreateGenericTable("Accountants");
IDataContext context = (IDataContext)Activator.CreateInstance(typeAccountants);
Then the rest is just as if you had a normal DataContext. Hope this helps someone else.