Интерфейсы и нарушение множественности в EF 4.1 Code-first - PullRequest
1 голос
/ 07 ноября 2011

Я пытаюсь определить цепочку поставок с поставщиками, дилерами и розничными продавцами. Эти объекты связаны классом Contract, который также определяет ProductLine и Продукты, с которыми они будут работать. Для данной ProductLine будет заключен договор между Поставщиком (единственным владельцем этой ProductLine) и Дилером, а затем еще один договор между этим Дилером и Розничным продавцом.

Проблема в том, что между двумя дилерами также заключен контракт, поэтому я попытался создать два интерфейса (ISeller и IBuyer). Поставщик реализует ISeller, Retailer реализует IBuyer, а Dealer реализует оба интерфейса:

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; }
}

Создание контрактов между Поставщиком / Дилером или Дилером / Розничным продавцом работает по назначению, но я получаю ' Ограничение кратности ' при попытке создать контракт Дилера / Дилера.

Ответы [ 2 ]

6 голосов
/ 09 ноября 2011

Кажется, что проблема с этим кодом - интерфейсы. Как сказал Слаума в комментариях, элементы интерфейса класса 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; }
}

Эта модель должна генерировать структуру базы данных, которая будет поддерживать ваш сценарий без какой-либо другой конфигурации. Однако это также позволило бы заключать контракты между любыми типами участников, но если вы попытаетесь отобразить множественное наследование в модели данных, вы получите что-то вроде this - подумайте, хотите ли вы усложнить вашу модель данных, чтобы сохранить эти ограничения .

0 голосов
/ 07 ноября 2011

Попытка использовать это:

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