Entity Framework сначала код отношения один ко многим - PullRequest
3 голосов
/ 21 сентября 2011

У меня первые шаги в EF 4.1. Поскольку я использовал NHibenate, подход с первым кодом кажется мне лучшим. У меня проблема с хорошим отображением отношений один-ко-многим (или многие-к-одному). Допустим, у меня есть 2 объекта:

class ClientModel
{
    int ClientID;
    string Name;
    virtual IList<OrderModel> Orders;
}

class OrderModel
{
    int OrderID;
    string Details;
    virtual ClienModel Client;
}

Когда я оставляю это так, при создании базы данных возникает ошибка - ключи в таблицах отсутствуют. Я понял, что могу это исправить, изменив имена ключей на ID (но это не соответствует моему соглашению об именах) или добавив аннотацию [Key]. Даже если я добавлю эту аннотацию, имена таблиц будут неправильными - как и имена классов, но с 's'. Поэтому я попытался использовать свободный API - я сделал сопоставления. Но если я установлю сопоставления, как здесь:

class ClientMapping
{
    ClientMapping()
    {
        this.HasKey(e => e.ClientID).Property(e => e.ID).HasColumnName("ClientID");
        this.Property(e => e.Name).HasColumnName("Name");
        this.HasMany(e => e.Orders).WithOptional().Map(p => p.MapKey("OrderID")).WillCascadeOnDelete();
        this.ToTable("Clients");
    }
}

class OrderMapping
{
    OrderMapping()
    {
        this.HasKey(e => e.OrderID).Property(e => e.OrderID).HasColumnName("OrderID");
        this.Property(e => e.Details).HasColumnName("Details");
        this.HasRequired(e => e.Client).WithMany().Map(p=>p.MapKey("Client")).WillCascadeOnDelete(false);
        this.ToTable("Orders");
    }
}

отношение между таблицами в базе данных удваивается. Как правильно делать отношения один-ко-многим с использованием подхода «сначала код»? Я думаю в правильном направлении или это неправильный подход?

EDIT

ОК, я сделал это так, как показал @ Eranga , но проблема все еще существует. Когда я получаю Клиента из базы данных, его свойство Orders имеет значение null (но в базе данных у него есть несколько Orders с Order.ClientID == Client.ClientID).

Ответы [ 2 ]

6 голосов
/ 21 сентября 2011

Вам необходимо отобразить оба свойства, участвующих в отношениях. Вам необходимо добавить столбец ClientID в таблицу заказов.

class ClientMapping
{
    ClientMapping()
    {
        this.HasKey(e => e.ClientID).Property(e => e.ID).HasColumnName("ClientID");
        this.Property(e => e.Name).HasColumnName("Name");

        this.HasMany(e => e.Orders).WithRequired(o => o.Client)
           .Map(p => p.MapKey("ClientID")).WillCascadeOnDelete();

        this.ToTable("Clients");
    }
}

class OrderMapping
{
    OrderMapping()
    {
        this.HasKey(e => e.OrderID).Property(e => e.OrderID).HasColumnName("OrderID");
        this.Property(e => e.Details).HasColumnName("Details");
        this.ToTable("Orders");
    }
}

Конфигурирование отношений с одной сущностью достаточно.

0 голосов
/ 07 декабря 2014

Это может помочь (это помогло мне, когда я не мог понять, как это работает):

Если бы у вас были такие классы:

class ClientModel
{
    int ClientId;
    string Name;
}

class OrderModel
{
    int OrderId;
    string Details;
    int ClientId;
}

Тогда это было быпредставляют 2 таблицы в вашей базе данных, которые «не будут» связаны друг с другом через внешний ключ (они будут связаны через ClientId в OrderModel), и вы можете получить данные типа «GetAllOrdersWithSomeClientId» и «GetTheClientNameForSomeClientId»из базы данных.НО проблемы могут возникнуть, когда вы удалите Client из базы данных.Потому что тогда все равно будет какое-то число Orders, которое будет содержать ClientId, которого больше нет в таблице Client и которое приведет к аномалиям в вашей базе данных.

virtual List<OrderModel> Orders;ClientModel) и virtual ClienModel Client;OrderModel) необходимы для создания отношения ака.внешний ключ между таблицами ClientModel и OrderModel.

Есть одна вещь, в которой я до сих пор не уверен.Что является int ClientId; в OrderModel.Я предполагаю, что оно должно иметь то же имя, что и ClientId в ClientModel, чтобы структура сущности знала, к каким 2 атрибутам должен подключиться внешний ключ.Было бы неплохо, если бы кто-то мог объяснить это подробно.

Кроме того, поместите это в свой конструктор DbContext, если что-то не получится:

this.Configuration.ProxyCreationEnabled = false;
this.Configuration.LazyLoadingEnabled = false;
...