Code first EntityConfiguration - entity-framework

Is it possible to modify / replace an entity configuration in a context that is being inherited in a different context?
Example: I have Context in a project called Data.Access in a solution called Framework. Its OnModelCreating function adds entity configurations thusly:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// TestEntityConfiguration is the configuration of an entity named TestEntity in the Framework solution
modelBuilder.Configurations.Add(new TestEntityConfiguration());
// multiple other configurations...
}
In another solution called FrameworkConsumer, I have a Local.Data.Access project that has a Context class which extends Context from Data.Access in the Framework solution. Its OnModelCreating function looks like this:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// Adds all the configurations from the Context in Data.Access in the Framework solution
base.OnModelCreating(modelBuilder);
// Other configurations local to the extended context go here...
}
My question is this. In the Local.Data.Access project in the FrameworkConsumer solution, if I wanted to add extra configuration settings or a different configuration for TestEntity, how can this be accomplished or can it be done? I've tried adding another configuration however, I get errors stating that this Entity (TestEntity) has already been configured. For now, my solution to add extra configuration was to use Database.ExecuteSqlCommand in the Dispose function in Local.Data.Access Context class. Not elegant, but it works. Any ideas / advice would be appreciated.
Thanks

You can put that configuration in another virtual method, that you can override if you need to change it. For instance:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// multiple other configurations...
SpecialConfigurations(modelBuilder);
}
protected virtual void SpecialConfigurations(DbModelBuilder modelBuilder)
{
// TestEntityConfiguration is the configuration of an entity named TestEntity in the Framework solution
modelBuilder.Configurations.Add(new TestEntityConfiguration());
// multiple other configurations...
}
And then override the SpecialConfigurations method.

Related

Is EF Core resistant to change the order of configurations in OnModelCreating?

Let's assume, we have following model configuration and migrations already applied
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Customer>()...
modelBuilder.Entity<Property>()...
...
modelBuilder.Entity<Address>();
}
Does it any difference whether new entity configuration will be added at the beginning in the middle or at the end of current configurations? What's more, does it affect migrations when the order of configuration will be totally changed through refactoring?
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
...
modelBuilder.Entity<Contact>();
...
modelBuilder.Entity<Address>();
...
modelBuilder.Entity<Customer>()...
modelBuilder.Entity<Property>()...
}
For explicit fluent configurations the order doesn't matter, and the entity configurations will override any conventions.
But if you are adding custom conventions, the order can matter, as documented in the section Convention Order here: http://entityframework.codeplex.com/wikipage?title=Custom%20Conventions
David

Entityframework Code First Singularize table name

I've tried the way it's mentioned in
EF4 Code First make tables names singular but in my case EF6 is not recognizing OnModelCreating(). It says "No suitable method found to override". Is there any alternate way or any way to fix it?
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
I am not certain of the ModelBuilder Type but I can say for a fact I just tested my older Code First on EF 6.1.3 and it works fine with this:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.HasDefaultSchema("dbo");
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
...
}
I think you needed DbModelBuilder versus ModelBuilder. I am not sure of that thread but know I just ran mine just now and that was the only thing I noticed differently. I learned EF Code First from two tutorials and this one by far was better than the other by leaps and bounds: http://www.entityframeworktutorial.net/code-first/entity-framework-code-first.aspx

Pluggable conventions in a database first environment

Working with entity framework 6+ we now have access to add custom Conventions to the model builder like this.
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Add(FilterConvention.Create<ITenantOwned, Guid>("TenantOwned", (e, tenantKey) => e.TenantKey == tenantKey));
modelBuilder.Conventions.Add(FilterConvention.Create<ISoftDelete>("SoftDeleted", e => e.Deleted == false));
base.OnModelCreating(modelBuilder);
}
However I am unable to get this to work because all of our projects have an EDMX file. When you allow your metadata to be read in through the goofy connection string OnModelCreating never gets called. I am fine with OnModelCreating never getting called except that so far as I can tell I am unable to access the modelBuilder at any other time in order to inject my own Conventions into the model.
So is is it actually the case that Conventions are unavailable to non code first users, or am I overlooking something.

How to exclude one table from automatic code first migrations in the Entity Framework?

I'm using the Entity Framework in the Code First mode with automatic migrations enabled. Now, I have one entity whose table should not be managed (migrated) by the EF. Is there a way of disabling automatic migrations for one specific entity (i.e. table)?
This is now possible in EF Core 5.0 using the ExcludeFromMigrations() method, but strangely enough you have to call the ToTable() method and then use the TableBuilder.
https://devblogs.microsoft.com/dotnet/announcing-entity-framework-core-efcore-5-0-rc1/#exclude-tables-from-migrations
public class ReportingContext : DbContext
{
public DbSet<User> Users { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<User>().ToTable(nameof(Users), t => t.ExcludeFromMigrations());
}
}
Another option that worked for me in EFCore 5.0 is to use SetIsTableExcludedFromMigrations:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<MyEntity>().Metadata.SetIsTableExcludedFromMigrations(true);
}
My TEMPORARY solution, only for dev environments.
I have a separate script that runs migration and program run does not check them. So in unexpected case I was possible to invoke Ignore<ContactView>() and run migrations with this line. When it was completed, I removed this line!
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// comment out this code after migrations are done
modelBuilder.Ignore<ContactView>();
}
It is possible by using another DbContext to access the table in question. Migrations are bound to one DbContext (see Is it possible to have automatic migrations for one DbContext and not for another in the same project?).
Not sure if this is the OP's exact scenario, but I had a table that I did not want a migration generated for. I accomplished this by using ToView instead of ToTable within the DbContext:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<MyTable>(entity => {
// Migration will not be generated for this table
entity.ToView("MyTable", "dbo");
entity.Property(e => e.FooBar).HasColumnType("DECIMAL(19,9)");
});
}
It feels a bit hacky to me, but maybe it's not -- because, after all, I'm just trying to "view" the table, not write to it...
[Tested with .NET Core EF 3.1.3]
You want to use the [NotMapped] annotation on that class/entity.

entity framework plural table names

I am trying to get EF 5 to generate singular table names. I have the following code in my DbContext...
public partial class LiveoModelContainer : DbContext
{
protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
base.OnModelCreating(modelBuilder);
}
}
We are using Model First, and have our own generated code to follow our internal development patterns. So we are not using the out of the box code gen that comes with EF. I have set pluralization to false in the edmx properties, in the Database Tools/O/R Designer, and removing the convention in the OnModelCreating above. However, the table names remain plural.
How do I fix this?