Много-много ли связи с таблицей соединений в Entity Framework? - PullRequest
7 голосов
/ 24 марта 2011

Я пытаюсь создать отношение «многие ко многим» в Entity Framework (сначала код), согласно следующему сообщению: Дизайн базы данных для ограниченного числа вариантов в MVC и Entity Framework?

Однако я не могу заставить его работать должным образом, и я уверен, что делаю что-то очень простое неправильно. Вот диаграмма, которую я не имею из моих попыток:

enter image description here

Смысл соединительной таблицы в том, что мне нужно иметь дополнительное свойство Level в отношениях, поэтому я не могу просто установить прямые отношения между Консультантом и Программой. Я добавил сущность ConsultantProgramLink вручную в конструкторе, а затем добавил ассоциации к Программе и Консультанту соответственно, выбрав добавление FK для каждого, а затем сделал их первичными ключами. Но когда я делаю это так, это не работает так, как я ожидал:

Если бы я установил прямую связь между Консультантом и Программой, я мог бы сослаться, например, на Консультанта. Программы в моем коде. Но это не работает сейчас с соединительной таблицей. Есть ли способ исправить это, или мне всегда нужно пройти через свойство junction (Consultant.ConsultantProgramLink.Programs)? В любом случае, даже если я попытаюсь пройти через свойство junction, это не поможет. Я могу использовать Consultant.ConsultantProgramLink в своем коде, но другая точка не дает мне свойства навигации «Программы» (которое по какой-то причине также стало просто «Программа», почему? .

Так что я делаю не так? Почему я не могу получить доступ к свойствам через точечную запись в моем коде?

1 Ответ

11 голосов
/ 24 марта 2011

Когда вы моделируете соединительную таблицу как сущность, вы действительно теряете прямое отношение «многие ко многим» между Consultant и Program. Вот как это работает. У вас будет прямое отношение «многие ко многим» или дополнительные свойства в соединительной таблице. Не оба. Если вы хотите и то и другое, вы можете попробовать создать собственное свойство Programs для Consultant и использовать запрос linq для получения связанных программ:

public IEnumerable<Program> Programs
{
    get
    {
        return this.ConsultantProgramLinks.Select(l => l.Program);   
    }
}

Пример также является объяснением вашей последней проблемы. Вы не можете иметь свойство Program в ConsultantProgramLink, потому что это набор связанных сущностей, а не одна сущность (она должна называться ConsultantProgramLinks). Свойство в сущности ConsultantProgramLink называется просто Program, поскольку оно представляет отдельную сущность, а не коллекцию.

Edit:

Если вам нужно, чтобы каждый Program автоматически связывался с каждым Consultant, вы должны применить его при создании нового Program. Открытая соединительная таблица как отдельная сущность, вероятно, позволит вам легко ее достичь:

var program = new Program();
...
context.Programs.AddObject(program);

var ids = from c in context.Consultants
          select c.Id;

foreach (var id in ids)
{
    var link = new ConsultantProgramLink
        {
            ConsultantId = id,
            Program = program
        };
    context.ConsultantProgramLinks.AddObject(link);
}

context.SaveChanges();

Если вы добавите новый Consultant, вам придется одинаково создавать ссылки на все программы.

Недостатком является то, что если у вас есть, например, 1000 консультантов, эта конструкция создаст 1001 вставку базы данных, где каждая вставка будет выполняться в отдельном цикле туда-обратно к базе данных. Чтобы избежать этого, единственный вариант - использовать хранимую процедуру или триггер в таблице программ.

...