在EF7中使用dbset和mappers有什么区别

时间:2017-07-18 12:01:19

标签: c# asp.net-core-mvc .net-core entity-framework-core onion-architecture

我开始在.net core中使用Entityframework 7Onion Architecture!我读了this教程,我认为这是学习以下主题的最佳案例。但是本教程的一部分在我的脑子里提出了一个大问题。就像你在这个链接页面看到的那样;在数据层我们有一些类是我们的模型!!

public class User : BaseEntity
{
    public string UserName { get; set; }
    public string Email { get; set; }
    public string Password { get; set; }
    public virtual UserProfile UserProfile { get; set; }
}

public class UserProfile : BaseEntity
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Address { get; set; }
    public virtual User User { get; set; }
}

以及正在映射上述模型的一些类!!

public class UserProfileMap
{
    public UserProfileMap(EntityTypeBuilder<UserProfile> entityBuilder)
    {
        entityBuilder.HasKey(t => t.Id);
        entityBuilder.Property(t => t.FirstName).IsRequired();
        entityBuilder.Property(t => t.LastName).IsRequired();
        entityBuilder.Property(t => t.Address);
    }
}

public class UserMap
{
    public UserMap(EntityTypeBuilder<User> entityBuilder)
    {
        entityBuilder.HasKey(t => t.Id);
        entityBuilder.Property(t => t.Email).IsRequired();
        entityBuilder.Property(t => t.Password).IsRequired();
        entityBuilder.Property(t => t.Email).IsRequired();
        entityBuilder.HasOne(t => t.UserProfile).WithOne(u => u.User).HasForeignKey<UserProfile>(x => x.Id);
    }
}

并在DbContext的OnModelCreating方法中使用此映射器类在数据库中创建以下模型作为表:

public class ApplicationContext : DbContext
{
    public ApplicationContext(DbContextOptions<ApplicationContext> options) : base(options)
    {
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        new UserMap(modelBuilder.Entity<User>());
        new UserProfileMap(modelBuilder.Entity<UserProfile>());
    }
}

我的一个大问题是:我们可以对db上下文中的每个实体使用DbSet<>,并避免编写映射器并在OnModelCreating dbcontext方法中实例化它们。为什么这个教程没有使用dbset?为什么我们要创建映射器!

2 个答案:

答案 0 :(得分:4)

  

我的大问题是:我们可以使用DbSet&lt;&gt;对于里面的每个实体   db上下文并避免编写映射器并将其实例化   dbcontext的OnModelCreating方法。为什么这个教程没有使用dbset   ?。为什么我们要创建映射器!

new UserMap(modelBuilder.Entity<User>());基本上是 EF Core 使用Fluent API配置和映射实体到DbSet的方式。

<强> DbSet&LT;&GT;对于db上下文中的每个实体 ,使用Mapper配置DbSet 是相同的。

在Entity Framework 6中,我们使用 EntityTypeConfiguration 并创建像this这样的映射类。与 Data Annotation 相比,它非常干净,并遵循单一责任原则

我们只需要the following code就可以使用反射自动配置数百个实体。

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
   ...
   var typesToRegister = Assembly.GetExecutingAssembly().GetTypes()
        .Where(type => !string.IsNullOrEmpty(type.Namespace) &&
             type.BaseType != null &&
             type.BaseType.IsGenericType &&
             type.BaseType.GetGenericTypeDefinition() == typeof (EntityTypeConfiguration<>));

   foreach (var type in typesToRegister)
   {
      dynamic configurationInstance = Activator.CreateInstance(type);
      modelBuilder.Configurations.Add(configurationInstance);
   }

   base.OnModelCreating(modelBuilder);
}

此外,我们可以使用Entity Framework Power Tools,并从现有数据库创建实体和映射配置。只需几分钟就可以将数百个表生成到类中。这对我们来说是一个很大的节省时间。

不幸的是,截至今天, EF Core 中无法使用EntityTypeConfiguration<T>。我认为我们中的很多人仍然希望使用新的EntityTypeBuilder<T>旧方法将映射配置保持在DbContext之外,尽管它不像我们在EF6中那样顺利。

答案 1 :(得分:3)

我只会解决你的大问题的一部分,这可能会改变你最初的假设:

  

为什么本教程没有使用dbset?为什么我们要创建映射器?

您错过了巨大点。再次检查教程并查找这段代码:

public class Repository<T> : IRepository<T> where T : BaseEntity
{
    private readonly ApplicationContext context;
    private DbSet<T> entities;   <---- HHHEEEERRREEEE

我已经为你标记了它。是。教程确实使用了DbSet&lt;&gt; 。他们将dbsets包装到&#34; repository&#34;只是洋葱建筑的一种便利和形式主义:它们暴露了&#34; IRepository&#34;从层而不是直接暴露DbSet - 只是为了保持对EntityFramework的引用,而不是让任何其他层知道EF在内部使用。但这并不意味着他们没有使用DbSets。显然,存储库使用DbSets。

这是因为DbSet和Mappings是完全不同的东西。映射定义了如何将类/属性映射到表/列,还添加了一些元数据,例如哪些列应该不为null(=应该是&lt;需要&#39;),要创建的索引/等等。

但所有这些映射都没有给你下载/插入/更新记录的方法。它只定义了数据库和类的外观。

对于执行操作,这里有DbSet。它定义了对映射器定义的数据进行操作的方法。