Если одна строка таблицы базы данных относится к нескольким строкам в другой таблице той же базы данных, то мы говорим, что между этими двумя таблицами существует отношение один ко многим.
Например: aстол со школами и стол со студентами.Каждая школа в таблице школ имеет ноль или более учеников из таблицы учеников.
В реляционной базе данных реализовано отношение «один ко многим» путем добавления дополнительного столбца к таблице «многие»: внешний ключк одной таблице.
В базе данных School-Student мы добавим внешний ключ к таблице Student, который будет указывать на школу, к которой принадлежит этот Student.Таким образом, все учащиеся школы с первичным ключом 4 будут иметь одно и то же значение для внешнего ключа: 4
Если вы будете следовать соглашениям по кодированию кода структуры сущности , у вас будет нечто подобноеto:
class School
{
public int Id {get; set;} // will become the primary key
public string Name {get; set;}
... // other properties
// every School has zero or more Students (one-to-many)
public virtual ICollection<Student> Students {get; set;}
}
class Student
{
public int Id {get; set;} // will become the primary key
public string Name {get; set;}
public DateTime BirthDate {get; set;}
... // other properties
// every Student belongs to exactly one School, using foreign key:
public int SchoolId {get; set;}
public virtual School School {get; set;}
}
The DbContext:
class SchoolContext : DbContext
{
public DbSet<School> Schools {get; set;}
public DbSet<Student> Students {get; set;}
}
Это все, что требуется структуре сущностей для идентификации ваших таблиц, столбцов таблиц и связи между таблицами.Только если вы хотите использовать разные идентификаторы или поведение, отличное от поведения по умолчанию, вам нужно будет добавлять атрибуты или использовать свободный API.
В структуре сущностей столбцы таблиц представлены не виртуальнымисвойства.Виртуальные свойства представляют отношения между таблицами (один-ко-многим, многие-ко-многим, ...)
Люди с опытом работы с базами данных склонны думать в операторах SQL, которые они переводят вLINQ.Однако использование виртуальных свойств упрощает запросы
Дайте мне имена всех учеников вместе с названием школы, которую они посещают.
var result = dbContext.Students.Join(dbContext.Schools, // join students and schools
student => student.SchoolId, // from Student take the SchoolId,
school => school.Id, // from School take the Id,
(student, school) => new // when they match, make a new object
{
StudentName = student.Name,
SchoolName = school.Name,
});
Использованиевиртуальные свойства облегчают жизнь:
var result = dbContext.Students.Select(student => new
{
StudentName = student.Name,
SchoolName = student.School.Name,
});
Словами: из коллекции учеников выберите из каждого ученика его имя и название его (единственной) школы
Поскольку я использовал виртуальные свойства, код выглядит намного проще.Платформа сущностей знает связь между таблицами и знает, что для этого необходимо внутреннее объединение.
Дайте мне названия всех школ с именами их учеников
var schoolsWithTheirStudents = dbContext.Schools.Select(school => new
{
Name = school.Name,
StudentNames = school.Students.Select(student => student.Name).ToList(),
});
На словах: из коллекции Школ выберите из каждой Школы ее имена, а из каждого Ученика в этой школе - его имя.
Если у вас есть структура сущностей один-ко-многими вы хотите сделать внутреннее соединение, начните со многих сторон (студенты).Если вы хотите сделать GroupJoin, начните с одной стороны (школы)