![](/img/trans.png)
[英]code -first Entity framework - Is this possible with inheritance and navigation properties?
[英]Entity Framework 6 - inheritance and navigation properties on base class
我对导航属性和继承有疑问。
这是我的问题:我有一个基本的Person
类以及从Person
继承的User
和Worker
类。 在数据库级别,我正在使用单表继承或按层次结构表(TPH)继承。 因此,有一个带有鉴别符列的表。
User
和Worker
需要有一个Company
关系,所以我想在Person
类上定义它。
我这样定义我的模型:
[Table("mydb.person")]
public abstract partial class Person
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long ID { get; set; }
public long? CompanyID { get; set; }
[ForeignKey("CompanyID")]
public virtual Company Company { get; set; }
...
}
public partial class User : Person
{
...
}
public partial class Worker : Person
{
....
}
[Table("mydb.company")]
public partial class Company
{
public Company()
{
this.People = new HashSet<Person>();
this.Users = new HashSet<User>();
this.Workers = new HashSet<Worker>();
}
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long ID { get; set; }
public virtual ICollection<Person> People { get; set; }
public virtual ICollection<User> Users { get; set; }
public virtual ICollection<Worker> Workers { get; set; }
...
}
现在,当我尝试执行查询以获取用户和相关公司时,例如:
dbSet.Where(u => u.Username == username).Include(x => x.Company).FirstOrDefault();
查询因以下异常而失败:
“字段”列表中的未知列“ Extent1.Company_ID”
如果我检查结果SQL,它看起来像这样:
SELECT
1 AS `C1`,
@gp2 AS `C2`,
`Extent1`.`ID`,
`Extent1`.`CompanyID`,
`Extent1`.`Username`,
...
`Extent1`.`Company_ID`
FROM `person` AS `Extent1`
WHERE `Extent1`.`Discriminator` = @gp1
它包括额外的Company_ID
列,该列不存在。
我尝试了几件事,但没有解决:
CompanyID
重命名为Company_ID
>它在SQL中生成Column_ID1
并引发相同的异常 Company
删除Users
and Workers
关系->抛出一个异常,它不知道如何映射User
和Company
实体: 无法确定类型“ Models.User”和“ Models.Company”之间的关联的主要终点。 必须使用关系流利的API或数据注释显式配置此关联的主要端。
Company
删除所有3个导航属性,则会引发与上述相同的映射异常 我目前没有“干净”的想法。 唯一可行的方法是进行一些肮脏的修改,定义子类上的所有关系,并在需要用户和工作人员的情况下分别进行查询和合并到基类中。
你有什么建议吗?
删除“用户和工作人员”集合属性。
public virtual ICollection<User> Users { get; set; }
public virtual ICollection<Worker> Workers { get; set; }
由于您的公司导航属性是在Person上定义的,因此相关的后向导航属性必须是Person的ICollection。
人员集合将包含所有关联的工作人员和用户。 用户和辅助程序这两个额外的属性被解释为全新的关系,因为您没有相应的属性,而用户或辅助程序EF上的外键实际上会生成它。
回答评论。 只是为了格式化为第二个答案;-)
如果您从公司开始,就渴望加载
var companies = db.Company.Include(p => p.People);
它将始终获得用户和工人。
如果您使用急切的加载方式,则始于人们。
var users = db.People.OfType<User>().Include(p => p.Company).ToList();
var companies = users.Select(p => p.Company).Distinct().ToList();
您公司的“人员”导航属性只有“用户”。
您也可以执行两个单独的语句,数据库上下文的修复程序将自动填充Navigation属性。
var company = db.Company.Where(p => p.ID > 100).ToList();
var copanyUsers = db.Company.Where(p => p.ID > 100)
.SelectMany(p => p.People).OfType<User>().ToList();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.