Entity framework 6 实体框架-为同一实体建模多个角色

Entity framework 6 实体框架-为同一实体建模多个角色,entity-framework-6,domain-model,Entity Framework 6,Domain Model,我有一个联络班 [Table("Contacts")] public class Contact { public string Id { get; set; } public string Name { get; set; } } 我从Contact继承了两个类: [Table("Employees")] public class Employee : Contact { public decimal Salary { get; set; } } [Table("S

我有一个联络班

[Table("Contacts")]
public class Contact
{
    public string Id { get; set; }
    public string Name { get; set; }
}
我从Contact继承了两个类:

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

[Table("Suppliers")]
public class Supplier : Contact
{
    public string TIN { get; set; }
}
我使用实体框架6.3作为我的ORM

我是否可以建立一个模型,使同一联系人既可以是员工也可以是员工 具有相同唯一Id的供应商

当我这样做时:

context.Employee.Add(emp);
context.Supplier.Add(sup);
context.Save();
显然,它不允许我添加记录。 我得到一个错误:

违反主键约束“PK\u dbo.Contacts”。无法在对象“dbo.Contacts”中插入重复键。重复键值为(C1)。\r\n语句已终止。“

我是否可以使供应商也与员工和供应商共享相同的Id 是否启用员工和供应商的插入/更新


谢谢

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

使用TPH时,每一行只能是一种类型,因此不能将同一行同时作为员工和供应商

还有另一种类型的映射,称为每类型表(TPT),它将为每种类型创建一个表,因此在您的案例3中,一个用于共享字段,一个用于每个依赖类型。这应该考虑到你所问的问题。(YMMV)

然而,似乎员工和供应商将被用于许多不同的领域,所以我建议您创建您的联系表,并将其与您的员工和供应商联系起来

[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();
db.Contacts.OfType().First();
在这两个例子中,我在上面展示了一个建模,在这两个例子中,您得到了三个表。我显示的只是FK,而不是TPT的3个表中的相同ID


您还可以查看每个类的表,这类似于TPT,但您没有为抽象/父类获取表,而是为每个依赖类型获取表,其中包含所有字段。我不认为这是您想要的,因为它会有重复的数据,但是,它确实意味着更少的连接。

谢谢。这个看起来很好。但是有没有可能通过IsA关系来实现这一点呢?正如我所说,使用TPT或TPC映射,您应该能够拥有与这两种类型相同的Id。不过,我认为你真的很反对框架这么做。谢谢。我尝试了TPT映射。我得到了上面帖子中提到的错误。是的,因为它认为您添加了一个新实体,所以它希望为每个依赖实体类型的联系人添加一行。
db.Contacts.OfType<Employee>().First();