Связь "много ко многим" с таблицей соединений в Entity Framework?
Я пытаюсь создать отношение "многие ко многим" в Entity Framework (сначала код), согласно следующему сообщению: Проектирование базы данных для ограниченного числа вариантов в MVC и Entity Framework?
Однако я не могу заставить его работать должным образом, и я уверен, что делаю что-то очень простое неправильным способом. Вот диаграмма, которой у меня нет из моих попыток:Суть таблицы переходов в том, что мне нужно иметь дополнительное свойство Level в Таблице переходов. отношения, поэтому я не могу просто пойти на прямые отношения между консультантом и программой. Я добавил сущность ConsultantProgramLink вручную в конструкторе, а затем добавил ассоциации к программе и консультанту соответственно, выбрав добавить FK для каждого, а затем сделал их оба первичными ключами. Но когда я делаю это так, это не работает, как я ожидал:
Если бы я провел прямую ассоциацию между консультантом и программой, я мог бы ссылаться, скажем, на консультанта.Программы в мой код. Но теперь это не работает с соединительным столом. Есть ли какой-либо способ исправить это, или я всегда должен проходить через свойство соединения (консультант.Консультантпрограммлинк.Программы)? В любом случае, даже если я попытаюсь пройти через свойство перехода, это не поможет. Я могу быть консультантом.ConsultantProgramLink в моем коде, но другая точка не дает мне навигационного свойства программы (которая почему-то тоже стала просто программой, почему? Могу ли я просто переименовать их, если я в конечном итоге получу доступ к ним вообще?).Так что же я делаю не так? Почему я не могу получить доступ к свойствам через точечные обозначения в моем коде?
1 ответ:
Как только вы моделируете таблицу соединений как сущность, вы действительно теряете прямое отношение "многие ко многим" между
Consultant
иProgram
. Вот как это работает. У вас будет либо прямое отношение "многие ко многим", либо дополнительные свойства в таблице соединений. Только не оба. Если вы хотите оба, вы можете попробовать создать пользовательское СВОЙСТВОPrograms
наConsultant
и использовать запрос linq для получения связанных программ:Этот пример также является объяснением вашей последней проблемы. Вы не можете иметь свойствоpublic IEnumerable<Program> Programs { get { return this.ConsultantProgramLinks.Select(l => l.Program); } }
Program
наConsultantProgramLink
, потому что это совокупность связанных сущностей, а не одна сущность (ее следует называтьConsultantProgramLinks
). Свойство в сущностиConsultantProgramLink
называется простоProgram
, потому что оно представляет собой единичную сущность, а не коллекцию.Правка:
Если вам нужно, чтобы каждый
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 вставку базы данных, где каждая вставка будет выполняться в отдельном цикле к базе данных. Чтобы избежать этого, единственный вариант-использовать хранимую процедуру или триггер в таблице программ.