Автоматическая фильтрация Entity Framework 6 для ленивой загрузки свойств навигации

Я реализую мягкое удаление в своем приложении со столбцом IsDeleted и использую EF 6 Code First для ORM. Я хочу автоматически фильтровать удаленные объекты при использовании оператора точки для доступа к свойствам навигации с отложенной загрузкой (со многими отношениями). Например: у пользователя много ролей

public class User
{
    private ICollection<Role> _roles;
    public virtual ICollection<Role> Roles
    {
        get { return _roles?? (_roles= new List<Role>()); }
        protected set { _roles= value; }
    }
}

и мне это нужно, когда я использую user.Roles, он будет автоматически фильтровать удаленные объекты, поэтому я не буду писать это явно, потому что это произойдет во многих местах:

user.Roles.where(u => u.IsDeleted == false).ToList();

Я думаю о EF Interceptor, но он будет применяться для всех запросов, и я все еще хочу загружать удаленные объекты в некоторых местах из-за бизнес-требований. Есть ли другой способ добиться этого эффективно?
Спасибо.


person N. Le    schedule 09.08.2016    source источник


Ответы (1)


Вы можете просто добавить «более правильное» свойство для инкапсуляции логики:

public class User
{
    private ICollection<Role> _roles;
    public virtual ICollection<Role> Roles
    {
        get { return _roles ?? (_roles = new List<Role>()); }
        protected set { _roles = value; }
    }

    public IEnumerable<Role> ActiveRoles
    {
        get { return this.Roles.Where(u => !u.IsDeleted); }
    }
}

Использование:

IEnumerable<Role> roles = user.ActiveRoles; // easy
  • Я предполагаю, что ваши объекты в конечном итоге реализуют какой-то IDeletable или что-то в этом роде.
    Это было опущено.

Вы также можете рассмотреть возможность реализации метода расширения IEnumerable<IDeletable> Active(), и беспорядок будет перемещен в часть использования: user.Roles.Active(). Не могу сказать, какой подход будет более элегантным для вашего случая.

person SimpleVar    schedule 09.08.2016
comment
Спасибо SimpleVar. Но в моем приложении есть тысячи таких коллекций, поэтому добавление дополнительных свойств оболочки или использование метода расширения Active() займет очень много времени. - person N. Le; 09.08.2016
comment
Когда вы делаете this.Roles, вы, по сути, загружаете все роли для пользователя. Фильтр применяется к загруженным объектам в памяти. - person user1176058; 20.03.2018