Reputation: 926
In EF 6 we could directly pass EntityTypeConfiguration to model builder to build maps and keep our configuration class separate from context without being too verbose in code.
Have they removed those maps in EF core. Is there a way to add configuration without doing it in model builder for every class?
Upvotes: 15
Views: 9761
Reputation: 2307
EntityFrameworkCore2.0 has a IEntityTypeConfiguration<TEntity>
which can be used as:
class ApplicationUserMap : IEntityTypeConfiguration<ApplicationUser>
{
public void Configure(EntityTypeBuilder<Customer> builder)
{
builder.ToTable("user", "identity");
builder.Property(p => p.Id)
.HasColumnName("id");
...
}
}
...
// OnModelCreating
modelBuilder.ApplyConfiguration(new ApplicationUserMap());
Upvotes: 21
Reputation: 62260
Is there a way to add configuration without doing it in model builder for every class?
It definitely is a lot of extra work if you have hundred of tables in database, and you have to configure each and every mapping class manually.
With the help of this extension method, you can achieve the desired result in few line of codes like good old EF 6.
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
Type[] types = typeof(EntityTypeConfiguration<>).GetTypeInfo().Assembly.GetTypes();
IEnumerable<Type> typesToRegister = types
.Where(type => !string.IsNullOrEmpty(type.Namespace) &&
type.GetTypeInfo().BaseType != null &&
type.GetTypeInfo().BaseType.GetTypeInfo().IsGenericType &&
type.GetTypeInfo().BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>));
foreach (var type in typesToRegister)
{
dynamic configurationInstance = Activator.CreateInstance(type);
ModelBuilderExtensions.AddConfiguration(modelBuilder, configurationInstance);
}
base.OnModelCreating(modelBuilder);
}
public abstract class EntityTypeConfiguration<TEntity> where TEntity : class
{
public abstract void Map(EntityTypeBuilder<TEntity> builder);
}
public static class ModelBuilderExtensions
{
public static void AddConfiguration<TEntity>(ModelBuilder modelBuilder, EntityTypeConfiguration<TEntity> configuration)
where TEntity : class
{
configuration.Map(modelBuilder.Entity<TEntity>());
}
}
public class UserMap : EntityTypeConfiguration<User>
{
public override void Map(EntityTypeBuilder<User> builder)
{
// Primary Key
builder.HasKey(t => t.Id);
...
}
}
Upvotes: 10
Reputation: 2469
The best way is to keep the configuration code away from the OnModelCreating
method. So you can do something like:
Create a class where you will store the actual configuration:
public class ApplicationUserConfiguration
{
public ApplicationUserConfiguration(EntityTypeBuilder<ApplicationUser> entity)
{
// Here you have all the good stuff
entity.ToTable("user", "identity");
entity.Property(p => p.Id)
.HasColumnName("id);
// And so on ....
}
}
And into your OnModelCreating
instantiate the new created class and pass the correct entity:
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
// Your custom configs here
new ApplicationUserConfiguration(builder.Entity<ApplicationUser>());
}
Is clean and a simple way to achieve the goal.
Upvotes: 15