Entity Framework 6 - 基类的继承和导航属性

Entity Framework 6 - inheritance and navigation properties on base class(Entity Framework 6 - 基类的继承和导航属性)

本文介绍了Entity Framework 6 - 基类的继承和导航属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

导航属性和继承有问题.

I have a problem with navigation properties and inheritance.

这是我的问题:我有一个基本的 Person 类和继承自 Person 的类 UserWorker.在数据库级别上,我使用单表继承或每层次表 (TPH) 继承.所以有一个带有鉴别器列的表.

This is my problem: I have a base Person class and classes User and Worker which inherit from Person. On the DB level I'm using single table inheritance or table per hierarchy (TPH) inheritance. So there a single table with a discriminator column.

UserWorker都需要有Company关系,所以我想在Person类.

Both User and Worker need to have a Company relation, so I would like to define it on the Person class.

我这样定义我的模型:

[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; }

    ...
}

现在,当我尝试进行查询以获取用户和相关公司时,例如:

Now, when I try to do a query to get the user and related company, for example:

dbSet.Where(u => u.Username == username).Include(x => x.Company).FirstOrDefault();

查询失败,出现以下异常:

The query fails with this exception:

字段列表"中的未知列Extent1.Company_ID"

Unknown column 'Extent1.Company_ID' in 'field list

如果我检查结果 SQL,它看起来像这样:

If I examine the result SQL it looks something like this:

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 列,该列不存在.

It includes the extra Company_ID column, which doesn't exist.

我尝试了一些东西,但没有成功:

I tried a few thing, nothing worked out:

  • 将列从 CompanyID 重命名为 Company_ID -> 它会在 SQL 中生成 Column_ID1 并引发相同的异常
  • Company 中删除 UsersWorkers 关系 -> 它会抛出一个异常,说它不知道如何映射 用户公司实体:
  • renaming the column from CompanyID to Company_ID -> it generates a Column_ID1 in SQL and throws the same exception
  • removing the Users and Workers relations from Company -> it throws an exception saying it doesn't know how to map User and Company entities:

无法确定之间关联的主体端类型Models.User"和Models.Company".这个的主要目的关联必须使用任一显式配置关系流式 API 或数据注释.

Unable to determine the principal end of an association between the types 'Models.User' and 'Models.Company'. The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations.

  • 如果我从 Company 中删除所有 3 个导航属性,则会引发与上述相同的映射异常
    • If I remove all 3 navigation properties from Company it throws the same mapping exception as above
    • 我目前没有干净"的想法.唯一可行的方法是做一些肮脏的修改,定义子类上的所有关系,并在需要用户和工作人员时在基类中进行单独的查询和合并.

      I'm out of "clean" ideas at the moment. The only thing that could work is to do some dirty hack, define all the relations on child classes, and do separate queries and merging in the base class if both users and workers are required.

      你有什么建议吗?

      推荐答案

      移除 Users 和 Workers 集合属性.

      Remove the Users and Workers collection properties.

      public virtual ICollection<User> Users { get; set; }
      
      public virtual ICollection<Worker> Workers { get; set; }
      

      由于您的公司导航属性是在 Person 上定义的,因此关联的后退导航属性必须是 Person 的 ICollection.

      As your Company navigation property is defined on Person the associated back navigation property has to be an ICollection of Person.

      People 集合将包含所有相关的工作人员和用户.两个额外的属性 Users 和 Worker 被解释为全新的关系,因为您在 User 或 Worker 上没有相应的属性和外键 EF 虚拟生成它.

      The People collection will contain all the associated workers and users. The two extra properties Users and Workers are interpreted as completely new relationships and because you do not have corresponding properties and foreign keys on User or Worker EF generates it virtually.

      这篇关于Entity Framework 6 - 基类的继承和导航属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:Entity Framework 6 - 基类的继承和导航属性

基础教程推荐