I have a requirement to create db context with a specific type of entity since i have multiple Db context on the solution. my problem is OnModelCreating we apply Configuration from the assembly builder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly()) So i want to apply configuration with only IEntityTypeConfiguration Type with a Entity has base model BaseEntitylike below
public class DaysOfWeekBuilder : IEntityTypeConfiguration<DaysOfWeek>
{
public void Configure(EntityTypeBuilder<DaysOfWeek> builder)
{
builder.ToTable("DaysOfWeek");
builder.Property(e => e.Name).HasMaxLength(15);
}
}
So DaysOfWeek Entity has base class BaseEntity
public class DaysOfWeek : BaseEntity
{
public string Name { get; set; }
}
How can we filter IEntityTypeConfiguration with a Entity has base model BaseEntity ?
Thank you
The documentation says you can add a predicate for filtering as a second argument.
In this case, the predicate will scan the types and for each type, will check if it implements the IEntityTypeConfiguration<T> interface and if T inherits BaseEntity.
builder.ApplyConfigurationsFromAssembly(
Assembly.GetExecutingAssembly(),
t => t.GetInterfaces().Any(i =>
i.IsGenericType &&
i.GetGenericTypeDefinition() == typeof(IEntityTypeConfiguration<>) &&
typeof(BaseEntity).IsAssignableFrom(i.GenericTypeArguments[0]))
);
I had a similar issue where EF Migration would fail because I had the same entity in multiple contexts. And Amir's answer definitely helped me. So based on @Amir's asnwer I made the following.
public static void ApplyConfigurationsForEntitiesInContext(this ModelBuilder modelBuilder)
{
var types = modelBuilder.Model.GetEntityTypes().Select(t => t.ClrType).ToHashSet();
modelBuilder.ApplyConfigurationsFromAssembly(
Assembly.GetExecutingAssembly(),
t => t.GetInterfaces()
.Any(i => i.IsGenericType
&& i.GetGenericTypeDefinition() == typeof(IEntityTypeConfiguration<>)
&& types.Contains(i.GenericTypeArguments[0]))
);
}
The point of this is that it looks at all the entities in the current dbcontext and only adds the configurations for the DbSets in the DbContext.
This solved the issue where I had multiple DbContexts in the same assembly and added the configurations by using modelBuilder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());
using ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly()) is especially bad to use if you have multiple contexts in one assembly - it can also make the initial model creation really slow on startup. The reason is that it adds all configurations to a DbContext irregardless of it having a DbSet corresponding to the configuration. As long as it is in the same assembly it is added.
The next step to solving my problem was then to exclude the DbSets from migration that are already being migrated from other DbContexts.
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.ApplyConfigurationsForEntitiesInContext();
modelBuilder.Entity<SomeEntity().Metadata.SetIsTableExcludedFromMigrations(true);
}
I think in the future I will just create separate DbContexts exclusively for migrations and have them in their own assembly. I dislike having code that are not relevant for production in these assemblies.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With