接口和多重性违反了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; }
}
在供应商/经销商或经销商/零售商之间创建合同按预期工作,但是当尝试创建经销商/经销商合同时,我得到'违反多重约束'。
看来这段代码的问题出在接口上。正如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; }
}