Entity Framework - 为同一实体建模多个角色

Entity Framework - Modeling multiple roles for same entity

我有联系人class

[Table("Contacts")]
public class Contact
{
    public string Id { get; set; }
    public string Name { get; set; }
}

我有两个 class 继承自联系人:

[Table("Employees")]
public class Employee : Contact
{
    public decimal Salary { get; set; }
}

[Table("Suppliers")]
public class Supplier : Contact
{
    public string TIN { get; set; }
}

我正在使用 Entity Framework 6.3 作为我的 ORM。

Can I model something where the same contact can be both Employee and Supplier with the same unique Id.

Employee emp = new Employee();
emp.Id = "C1";
emp.Name = "Employees";
emp.Salary = 10000;
emp.TrackingState = TrackingState.Added;

Supplier sup = new Supplier();
sup.Id = "C1";
sup.Name = "Employees";
sup.TIN = "ABC";
sup.TrackingState = TrackingState.Added;

当我这样做时:

context.Employee.Add(emp);
context.Supplier.Add(sup);
context.Save();

很明显,它不允许我添加记录。 我得到一个错误:

"Violation of PRIMARY KEY constraint 'PK_dbo.Contacts'. Cannot insert duplicate key in object 'dbo.Contacts'. The duplicate key value is (C1).\r\nThe statement has been terminated."

Can I make the Supplier also share the same Id as that of employee and enable insert / update of employee and supplier?

谢谢

我假设您没有进行任何特定的继承映射,默认情况下会将其映射为每个层次结构 (TPH) 继承的 Table。通过此映射,您将获得一个 Db table,其中包含基本类型中所有字段的聚合以及带有鉴别器字段的依赖类型,以了解应具体化该行的类型。这允许在您要求类型的地方进行查询。

对于 TPH,每一行只能是一种类型,因此同一行不能既是员工又是供应商。

您可以执行另一种类型的映射,称为 Table 每类型 (TPT),它将为每种类型创建一个 table,因此在您的情况 3 中,一个用于共享字段,每个依赖类型一个。这应该允许你问什么。 (YMMV)

但是,似乎 Employee 和 Supplier 会在很多不同的领域中使用,因此我建议您创建联系人 table 并将其与您的员工和供应商相关联。

[Table("Contacts")]
public class Contact
{
    public string Id { get; set; }
    public string Name { get; set; }
}

[Table("Employees")]
public class Employee
{
    public string Id { get; set; }
    public string ContactId { get; set; }
    public decimal Salary { get; set; }

    public Contact Contact { get; set; }
}

[Table("Suppliers")]
public class Supplier
{
    public string Id { get; set; }
    public string ContactId { get; set; }
    public string TIN { get; set; }

    public Contact Contact { get; set; }
}

现在您可以查询员工:

db.Employees.Include(e => e.Contact).First();

或供应商:

db.Employees.Include(e => e.Contact).First();

这可能比您需要的继承查询更清晰:

db.Contacts.OfType<Employee>().First();

在我上面显示的 Has A 建模和 Is A Modeling with TPT 中,您将获得三个 table。你只是在我展示的内容中有 FK 而不是在 3 tables 中使用 TPT 的相同 ID。

还有 Table Per Class 你可以看看,这类似于 TPT 但你没有 table abstract/parent class,而你会得到每个依赖类型的 table,其中包含所有字段。我认为这不是您想要的,因为它会有重复数据,但是,它确实意味着更少的连接。