问题描述
我正在使用EntityFramework Core,Code First和Fluent Api定义模型数据库,并且遵循有关地图继承策略的情况:
I'm using EntityFramework Core, Code First and Fluent Api to define model database, and i've follow situation about strategy of map inheritance:
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
public class User : Person
{
public string UserName { get; set; }
public string Password { get; set; }
}
public class Employee : Person
{
public decimal Salary { get; set; }
}
public class Customer:Person
{
public long DiscountPoints { get; set; }
}
业务逻辑
在这种情况下,用户,员工和客户是人,但是员工和客户也是用户,员工也可以成为客户.并且每种类型都在不同的应用环境中使用.
In this case, users, employees and customers are people, however employees and customers are also users, as well as an employees can become a customer. And each type is used in distinct appication contexts.
我实现了这种方式,以避免不必要地使用其他应用程序上下文中的值.
I implemented this way to not use values from other application contexts unnecessarily.
问题:
-
映射数据库模型的最佳实践是什么?按层次结构类型还是按类型表?考虑到许多情况, TPT通常是一种反模式,以后会导致严重的性能问题.根据 EF问题#2266
a.如果是TPH,如何使用鉴别符字段来使用多种类型?
a. If TPH, how to use discriminator field to many types?
b.如果是TPT,如何在EF Core 1.0中使用此策略?
b. If TPT, how to use this strategy in the EF Core 1.0?
感谢您的关注与合作
推荐答案
在使用EF内核(已经习惯EF6,并且广泛使用每种类型的表)时,我简要地研究了这一点.
I looked into this briefly when playing with EF core, having been used to EF6, and extensively used table-per-type.
1a)我的经验是,如果仅将每种实体类型作为DbSet添加到上下文中,则默认映射会做得很好.如有必要,您可以在DbContext的OnModelBuilding覆盖中进行配置:
1a) My experience is that the default mappings do quite well if you just add each entity type as a DbSet to your context. If necessary then you can configure this in the OnModelBuilding override in your DbContext:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Person>()
.HasDiscriminator<string>("person_type")
.HasValue<Employee>("employee")
.HasValue<Customer>("customer");
}
1b)当前您不能将TPT与EF核心一起使用.它计划在将来的发行版中使用,目前在 EF核心路线图上列为高优先级"
1b) At present you can't use TPT with EF core. It is planned for future releases and is currently listed as High Priority on the EF core roadmap
2)如果我们采用严格的DDD原理,则业务层应尽可能紧密地对现实生活域进行建模/镜像,并且不受应用程序数据层的影响.就我个人而言,我认为如上所述的继承是现实生活中的一个很好的反映.但是,EF核心团队似乎处于偏重于继承"的阵营中,这可能会导致领域模型,例如:
2) If we are employing strict DDD principles then the business layer should model/mirror the real-life domain as closely as possible and not be influenced by the data layer of an application. Personally I think that inheritance as you have laid out above is a good mirror of a real-life situation. However, the EF core team seem to be in the "favour composition over inheritance" camp, which might lead to domain models such as:
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
public class User
{
public int Id {get;set;}
public Person Person {get; set;}
public int PersonId {get;set;}
public string UserName { get; set; }
public string Password { get; set; }
}
public class Employee
{
public int Id {get; set;}
public User User {get; set;}
public int UserId {get;set;}
public decimal Salary { get; set; }
}
public class Customer
{
public int Id {get;set;}
public User User {get; set;}
public int UserId {get;set;}
public long DiscountPoints { get; set; }
}
这些实体随后将存储在单独的表中,它们之间具有外键关系.员工向客户的过渡也将涉及创建一个具有与员工相同的用户属性的新客户,例如
These entitites would then be stored in separate tables, with foreigh-key relationships between them. The transition of an employee to being a customer as well, would involve creating a new customer, with the same user property as the employee, e.g.
public void CreateCustomerFromEmployee(int employeeId) {
var employee = context.Employees.Where(e => e.Id == employeeId).SingleOrDefault();
context.Customers.Add(new Customer()
{
UserId = employee.UserId,
DiscountPoints = 0
});
context.SaveChanges();
}
这篇关于在EntityFramework Core中映射继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!