2011-11-07 33 views
1

我正在尝试定义与供应商,经销商和零售商的供应链。这些实体受合同类的约束,该类还定义了ProductLine和他们将使用的产品。 对于给定的ProductLine,供应商(该ProductLine的唯一所有者)和经销商之间会有合同,然后是该经销商和零售商之间的另一个合同。EF 4.1上的接口和多重约束冲突代码优先

问题是两个经销商之间也有合同,所以我尝试创建两个接口(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; } 
} 

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

+0

你可以看看从你的类设计中生成的数据库模式吗?这可能会揭示为什么这种关系有问题。 –

+0

是的,我忘记提到合约表的布局有点奇怪: Id | Supplier_Id | Dealer_Id |零售商_Id 这种方式很明显,我不能在同一合同中拥有两个经销商。也许我应该使用自定义映射来帮助EF了解我正在尝试做什么。问题是我对Fluent API不太熟练。 :) –

+0

那么,那是你的问题。尽管如此,我还不太了解EF Code First,所以这是我个人可以提供的所有帮助。 –

回答

6

看来,这段代码的问题是接口。正如Slauma在评论中所说的那样,Contract类的接口成员根本不会被映射,因为EF不知道哪些实体 - 供应商,代理商或两者 - 映射到卖方成员。

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

你需要做的是有实体继承。经销商既可以是卖方也可以是买方,所以你不能拥有2个独立的类,因为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; } 
} 

这种模式应该产生一个能够支持您的方案,没有任何其他的配置数据库结构。然而,它也允许任何类型的参与者之间的合同,但如果你试图在数据模型中映射多重继承,你最终会得到类似于this的东西 - 考虑是否想使数据模型复杂化以保留这些约束。

+0

+1:这看起来不错! (一点:我认为你的意思是'[InverseProperty(...)]'属性,而不是'[ForeignKey(...)]'。) – Slauma

+0

谢谢。更正:) –

+0

非常感谢!看起来我们在这里有一个赢家。我可以使用自定义实体验证来抑制供应商/供应商与零售商/零售商之间签订的合同,因此这不成问题。 –

0

尝试使用这一个:

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