Страницы

Поиск по вопросам

пятница, 2 ноября 2018 г.

Как получить связанные объекты при помощи EF?

Предположим у нас есть следующая структура классов:
public class User { public int Id {get;set;} //прочие свойства public int RoleId {get;set;}
public Role Role {get;set;} } public class Role { public int Id {get;set;} //прочие свойства public ICollection Users {get;set;} public ICollection Permissions {get;set;}
public Role() { Permissions = new List() } } public class Permission { public int Id {get;set;} //прочие свойства public ICollection Roles {get;set;}
public Permission() { Roles = new List(); } }
Как модифицировать указанные выше классы что бы можно было получить связанные сущности средствами Entity Framework?


Ответ

Для того что бы получить связанные объекты средствами Entity Framework существует несколько способов:
Eager loading - жадная загрузка; Lazy loading - ленивая загрузка; Explicitly lоading - явная загрузка;
Жадная загрузка - процесс при котором необходимо указать сущности которые необходимо загрузить сразу, это достигается путем указания необходимых сущностей при помощи метода .Include()
В этом случае для будет сформирован один запрос к бд который вернет все необходимые данные.
Ленивая загрузка - процесс при котором связанные сущности подгружаются при первом обращении, необходимые свойства должны быть объявлены с указанием модификатора доступа virtual
В данном случае при обращение к навигационному свойству будет формироваться запрос к бд для получения необходимых данных
Явная загрузка - процесс при котором связанные сущности подгружаются только если они явно подключены при помощи метода .Load()
в данном случае связанные сущности не будут подгружены до момента их подключения при помощи .Load()
Универсального решения о выборе между ленивой/явной и жадной загрузке - нет.
Загружать много редко используемой информации (особенно часто изменяемой) - не эффективно, еще более не эффективно использовать n+1 запросов вместо одного, так как ленивая загрузка будет означать выполнение отдельного запроса для каждого объект. Если нужно, то можно использовать .Load() вместо .Include()

Например:
Жадная загрузка
var user = context.Roles.Where(x=>x.Name.Contains("Admin")).Include(x=>x.Permissions)
Ленивая загрузка
Установим модификатор доступа virtual у свойства Role у класса User
public virtual Role Role {get;set;}
тогда получить роль пользователя можно будет получить так:
//получаем необходимого пользователя var user = context.Users.Where(x=>x.Id==5) //При обращении к свойству будет выполнен запрос к бд получающий связанную сущность. var userRole = user.Role;
Явная загрузка
может быть использована при отключенной ленивой загрузке(context.Configuration.LazyLoadingEnabled = false;), либо при отсутствии модификатора доступа virtual у необходимого свойства
var role = context.Roles.Where(x=>x.Name.Contains("Admin")).Single();
что бы получить связанные сущности в этом случае необходимо поступить так:
var usersRole = context.Entry(role).Collection(x => x.Users).Load();

Комментариев нет:

Отправить комментарий