Как правило, отношения «многие ко многим» в Linq2SQL (и Entity Framework) создаются путем введения таблицы ассоциации , содержащей только первичные ключи из двух таблиц, которые вы хотите связать, и места каждой строки. соответствует ассоциации.
Поскольку ваши Role
и Object.Role
могут быть трудно разделить в попытке объяснить это, я приведу другой пример: в школе у каждого учителя может быть много учеников, и у каждого ученика может быть много учителей. , Структура таблицы для представления этого будет тогда
Teachers Students StudentTeacherRelations
******** ******** ***********************
TeacherId StudentId TeacherId
FirstName FirstName StudentId
etc... etc...
Теперь Linq2SQL и EF достаточно умны, чтобы распознавать это как отношение «многие ко многим» и вводить навигационные свойства в вашей модели. POCO с соответствующими свойствами для объекта Student может выглядеть следующим образом:
public class Student
{
public int StudentId { get; set; }
public string FirstName { get; set; }
// etc
public IEnumerable<Teacher> Teachers { get; }
}
Если это настроено правильно, преобразователь O / R автоматически заполнит свойство Teachers
.
Обновление: В ответ на комментарии, вот как я структурировал бы остальную часть базы данных, если бы я хотел включить сценарий, в котором каждый учитель может дать некоторым ученикам домашнюю работу, состоящую из ряда вопросов. :
HomeworkAssignments Questions Answers
******************* ********* *******
HomeworkAssignmentId (pk) QuestionId (pk) AnswerId (pk)
... HomeworkAssignmentId (fk) QuestionId (fk)
... StudentId (fk)
...
StudentHomeworkAssignmentRelations TeacherHomeworkAssignmentRelations
********************************** **********************************
StudentId (fk) Teacherid (fk)
HomeworkAssignmentId (fk) HomeworkAssignmentId (fk)
Как видите, здесь довольно много таблиц. Однако эта структура позволяет каждому учителю создавать множество домашних заданий, а затем раздавать каждое задание нескольким студентам. У вас будет навигационное свойство Student.HomeworkAssignments
типа IEnumerable<HomeworkAssignment>
, с помощью которого вы сможете найти все вопросы, на которые должен ответить студент. Для каждого опубликованного ответа вы сохраняете строку в таблице Answers
, которая связана как с вопросами, так и со студентами отношениями «один ко многим» - каждый ответ может принадлежать только одному вопросу и предоставляться только одним студентом.
Ключевым моментом здесь является то, что вам не нужно иметь доступ к каждому ответу, предоставленному студентом напрямую - и в Linq2SQL, и в EF можно запрашивать данные из многих таблиц одновременно различными способами. Одним из таких способов является
var answersToTheLastExam = context.Students
.SelectMany(s => s.HomeworkAssignments)
.OrderBy(ha => ha.Date) // this might need modifying to get the last one first
.First(ha => ha.Questions.Count() > 0)
.SelectMany(ha => ha.Questions)
.SelectMany(q => q.Answers)
.Where(a => a.StudentId == myId)
Обратите внимание, что этот код не проверен и может работать не так, как я говорю. Я просто стараюсь изо всех сил с моей головы здесь =)