我开始在.net core
中使用Entityframework 7
和Onion 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?为什么我们要创建映射器!
答案 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。它定义了对映射器定义的数据进行操作的方法。