接口和多重性违反了EF 4.1代码优先的约束

本文关键字:代码 约束 EF 多重性 接口 | 更新日期: 2023-09-27 18:13:49

我正在尝试定义一个包含供应商、经销商和零售商的供应链。这些实体由一个Contract类绑定,该类还定义了ProductLine和它们将使用的产品。对于给定的产品线,供应商(该产品线的唯一所有者)与经销商之间将签订一份合同,然后该经销商与零售商之间将签订另一份合同。

问题是两个经销商之间也有一个合同,所以我尝试创建两个接口(ISeller和IBuyer)。供应商实现ISeller,零售商实现IBuyer,经销商实现这两个接口:

public class Supplier : ISeller
{
    public int Id { get; set; }
    public virtual ICollection<Contract> Contracts { get; set; }
}
public class Dealer : ISeller, IBuyer
{
    public int Id { get; set; }
    public virtual ICollection<Contract> Contracts { get; set; }
}
public class Retailer : IBuyer
{
    public int Id { get; set; }
    public virtual ICollection<Contract> Contracts { get; set; }
}

合同然后将ISeller绑定到IBuyer,如下所示:

public class Contract
{
    public int Id { get; set; }
    public virtual ISeller Seller { get; set; }
    public virtual IBuyer Buyer { get; set; }
}

在供应商/经销商或经销商/零售商之间创建合同按预期工作,但是当尝试创建经销商/经销商合同时,我得到'违反多重约束'。

接口和多重性违反了EF 4.1代码优先的约束

看来这段代码的问题出在接口上。正如Slauma在评论中所说,Contract类的接口成员根本没有映射,因为EF不知道,例如,哪些实体——供应商、经销商或两者——映射到卖方成员。

从另一个方向来看,我们知道每个供应链参与者都有多个合同。这将导致合同表中的Supplier_id、Dealer_id、Reseller_id列。从EF的角度来看,供应商和经销商没有共同点,零售商和经销商也没有共同点。

你需要做的是拥有实体继承。经销商可以同时是卖方和买方,所以你不能有两个单独的类,因为c#不允许多重继承。定义ContractParticipant基础实体,并从它继承供应商、经销商和零售商。然后您的数据模型看起来像这样:

public abstract class ContractParticipant
{
    public int Id { get; set; }
    [InverseProperty("Seller")]
    public virtual ICollection<Contract> SellerContracts { get; set; }
    [InverseProperty("Buyer")]
    public virtual ICollection<Contract> BuyerContracts { get; set; }
}
public class Supplier : ContractParticipant
{
    <...other properties here...>
}
public class Dealer : ContractParticipant
{
    <...other properties here...>
}
public class Retailer : ContractParticipant
{
    <...other properties here...>
}
public class Contract
{
    public int Id { get; set; }
    public virtual ContractParticipant Seller { get; set; }
    public virtual ContractParticipant Buyer { get; set; }
}

该模型应该生成支持您的场景的数据库结构,而不需要任何其他配置。然而,它也允许任何类型的参与者之间的契约,但是如果你试图在数据模型中映射多重继承,你最终会得到这样的结果——如果你想使你的数据模型复杂化以保持这些约束,请考虑一下。

尝试使用这个:

public class Contract
{
    public int Id { get; set; }
    public virtual Seller Sellers { get; set; }
    public virtual Buyer Buyers { get; set; }
}