Страницы

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

пятница, 13 декабря 2019 г.

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

#c_sharp #entity_framework


Предположим у нас есть следующая структура классов:

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?
    


Ответы

Ответ 1



Для того что бы получить связанные объекты средствами 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();

Ответ 2



Если используются сложные объекты, например вы хотите получить Users вместе в Roles, можно пользоваться var a = context.Users.Include(w=>w.Roles); Но я не до конца понял ваш вопрос

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

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