2013-05-06 5 views
0

Я использую Entity Framework 5.0,Entity Framework Связывание таблиц

Сценарий

"Организация" имеет список "клиентов" и список "Периоды" и «CurrentPeriodID» В начале каждого периода некоторые или все «Клиенты» связаны с этим «Период», это я сделал с использованием таблицы ссылок, и это работает O K, поэтому, когда я делаю «Организация-> Период-> Клиенты» Я получаю список «Клиенты» для «Период».

Далее мне нужно добавить некоторые объекты («Деятельность») к «Клиентам» за «Период» так я получаю «Organisation-> период-> Client-> Активизирует» эти не будет единственным, в конце концов, будет несколько других навигационных свойств, которые необходимо будет добавить в «Клиенты» и «Мероприятия», и все они должны быть «Период» связанных, I также должны быть в состоянии сделать (если возможно) «Организация-> Период-Мероприятия».

Вопрос

Что бы быть лучшим способом реализации «деятельности» для «Organisation-> Период-Клиент», я не против того, каким образом это делается Code First Reverse Engineering и т.д. Кроме того, на создание «Организация» объекта я мог загрузить текущий «Период» объекта с помощью «CurrentPeriodID» значение, которое хранится в «Организация» объекта.

Благодаря

ответ

0

Для меня это звучит, как вам нужно дополнительное юридическое лицо, которое соединяет Period, Client и Activity, давайте назовем его ClientActivityInPeriod. Эта сущность - и соответствующая таблица - имела бы три внешних ключа и три ссылки (и никакие коллекции). Я бы сделал первичный ключ этого объекта композицией из трех внешних ключей, потому что эта комбинация должна быть уникальной, я думаю. Это будет выглядеть следующим образом (в Code-First стиль):

public class ClientActivityInPeriod 
{ 
    [Key, ForeignKey("Period"), Column(Order = 1)] 
    public int PeriodId { get; set; } 

    [Key, ForeignKey("Client"), Column(Order = 2)] 
    public int ClientId { get; set; } 

    [Key, ForeignKey("Activity"), Column(Order = 3)] 
    public int ActivityId { get; set; } 

    public Period Period { get; set; } 
    public Client Client { get; set; } 
    public Activity Activity { get; set; } 
} 

Все три внешних ключей требуется (поскольку свойства не обнуляемым).

Period, Client и Activity могут иметь коллекции отсылая к этому лицу (но они не должны), например, в Period:

public class Period 
{ 
    [Key] 
    public int PeriodId { get; set; } 

    public ICollection<ClientActivityInPeriod> ClientActivities { get; set; } 
} 

Вы не можете иметь навигационные свойства как набор Clients в Period, который будет содержать все клиенты, которые имеют какие-либо действия за данный период, потому что для этого требуется иметь внешний ключ от Client до Period или таблицу ссылок «многие-ко-многим» между Client и Period. Внешний ключ или таблица ссылок будут заполнены только в том случае, если у клиента есть действия в этом Period. Ни EF, ни база данных не помогут вам в такой бизнес-логике. Вам нужно было запрограммировать это и убедиться, что отношения обновлены правильно, если действия добавляются или удаляются из периода, что подвержено ошибкам, и риск для вашей согласованности данных.

Вместо этого вы бы принести клиентам, которые имеют деятельность в данный период 1 запросом, а не с помощью свойства навигации, например, с:

var clientsWithActivitiesInPeriod1 = context.Periods 
    .Where(p => p.PeriodId == 1) 
    .SelectMany(p => p.ClientActivities.Select(ca => ca.Client)) 
    .Distinct() 
    .ToList();