При использовании реляционной базы данных каждому объекту в базе данных понадобится идентификатор, а если объект «принадлежит» другому объекту в другой таблице, вам потребуется внешний ключ. Вы не можете обойтись без этого.
К счастью, сущностный каркас достаточно умен, поэтому, если вы его правильно спроектируете, вы редко будете использовать внешние ключи для выполнения (групповых) объединений. Вы обычно используете виртуальные свойства.
В структуре сущностей классы представляют таблицы вашей базы данных. Столбцы в таблицах представлены не виртуальными свойствами класса. Виртуальные свойства представляют отношения между классами.
Итак, у вас есть BaseEntity
и три специальных типа BaseEntities
: Employers
, Employees
и Clients
.
Каждый Employer
имеет ноль или более Employees
; каждый Employee
имеет ровно одно Employer
: простое отношение «один ко многим». Для этого каждому Employee
нужен внешний ключ к Employer
, к которому он принадлежит, нравится вам это или нет. К счастью, вам не придется его использовать.
Аналогично, существует отношение «один ко многим» между Employer
и Client
: каждый Employer
имеет ноль или более Clients
, каждый Client
принадлежит ровно одному Employer
с использованием внешнего ключа .
Использование сущности Первый код соглашения платформы Ваши классы нуждаются в небольшом изменении: отношения между таблицами должны быть помечены как виртуальные.
class Employer : BaseEntity
{
public int Id {get; set;}
// every Employer has zero or more Employees:
public virtual ICollection<Employee> Employees { get; set; }
// every Employer has zero or more Clients:
public virtual ICollection<Client> Clients { get; set; }
...
}
class Employee : BaseEntity
{
public int Id {get; set;}
// every Employee belongs to exactly one Employer, using a foreign key:
public int EmployerId {get; set;}
public virtual Employer Employer { get; set; }
...
}
class Client : BaseEntity
{
public int Id {get; set;}
// Every Client belongs to exactly one Employer, using foreign key:
public int EmployerId { get; set; }
public virtual Employer Employer { get; set; }
...
}
Важным изменением является то, что отношения между таблицами помечены как виртуальные
Примечание. Возможно, вам не нужны целые числа для первичных ключей. Это не сильно изменит идею.
Для выполнения запросов, которые (группируют) присоединяются к таблицам, вам не нужно использовать внешние ключи,
GroupJoin
Дайте мне всех (или некоторых) работодателей со всеми (или некоторыми) из его клиентов и сотрудников.
Для этого вы бы использовали GroupJoin: каждый выбранный Работодатель имел бы подгруппу Клиентов и Сотрудников. С структурой сущностей вам не нужно делать соединение самостоятельно:
var result = dbContext.Employers // From every employer in the sequence ofall Employers
.Where(employer => ...) // or only some of them
.Select(employer => new // make one new object
{
// select only the properties you actually plan to use
Id = employer.Id,
Name = employer.Name,
Employees = employer.Employees
.Where(employee => ...) // only if you do not want all Employees
.Select(employee => new
{
// again, select only the properties you plan to use
Id = employee.Id,
Name = employee.Name,
...
})
.ToList(),
Clients = employer.Clients
.Where(client=> ...) // only if you do not want all Clients
.Select(client => new
{
...
})
.ToList(),
});
Entity Framework знает, что вы разработали один-ко-многим, и сделает правильное соединение для вас. Хотя вы не упомянули какой-либо внешний ключ, структура сущности знает, какие внешние ключи используются.
Обратите внимание, что таким образом вы также получаете Работодателей, у которых нет Клиентов или Сотрудников
Inner Join
Если вам не нужны «объекты с его подобъектами» (GroupJoin), а плоский результат (более похожий на «Join»), начните с подобъекта:
Дайте мне всех (или некоторых) клиентов с их работодателем
var result = dbContext.Clients.Select(client => new
{
Id = client.Id,
Name = client.Name,
...
Employer = new
{
Id = client.Employer.Id,
...
},
});
Entity Framework знает, что вы разработали один-ко-многим, и сделает правильное соединение для вас.
Обратите внимание, что вы не получите работодателей без клиентов.