【问题标题】:Entity Framework core configurations实体框架核心配置
【发布时间】:2017-03-28 13:00:43
【问题描述】:

在 EF 6 中,我们可以直接将 EntityTypeConfiguration 传递给模型构建器以构建地图,并将我们的配置类与上下文分开,而不会在代码中过于冗长。

他们是否删除了 EF 核心中的这些映射。有没有办法在不为每个类的模型构建器中添加配置?

【问题讨论】:

    标签: entity-framework asp.net-core entity-framework-core


    【解决方案1】:

    EntityFrameworkCore2.0 有一个IEntityTypeConfiguration<TEntity>,可以用作:

    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());
    

    【讨论】:

      【解决方案2】:

      最好的方法是让配置代码远离OnModelCreating 方法。所以你可以这样做:

      创建一个用于存储实际配置的类:

      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 ....
          }
      }
      

      并在您的OnModelCreating 中实例化新创建的类并传递正确的实体:

      protected override void OnModelCreating(ModelBuilder builder)
      {
          base.OnModelCreating(builder);
      
          // Your custom configs here
          new ApplicationUserConfiguration(builder.Entity<ApplicationUser>());
      }
      

      是实现目标的简洁且简单的方法。

      【讨论】:

      • 做了类似的事情...而不是不同的类,我为每个类创建了一个静态方法 Configure () 并传递了构建器
      • @Jajan 这也是我的第一个想法/尝试。但我想避免对 EntityFramework 的不必要引用,因为我希望我的“实体”可以跨项目和平台重用。只是我的 2 ct ;)。您的解决方案与其他解决方案一样有效,没有任何问题。
      【解决方案3】:

      有没有办法在模型构建器中添加配置而不做 每个班级?

      如果你在数据库中有数百个表,那肯定是很多额外的工作,而且你必须手动配置每个映射类。

      this extension method 的帮助下,您只需几行代码就可以达到预期的效果,例如良好的旧 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);
              ...
          } 
      }
      

      【讨论】:

        最近更新 更多