【问题标题】:Entity Framework 6 automatic filtering for lazy loading navigation propertiesEntity Framework 6 自动过滤延迟加载导航属性
【发布时间】:2016-08-09 01:18:00
【问题描述】:

我正在使用 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 拦截器,但它适用于所有查询,并且由于业务需求,我仍然想在某些地方加载已删除的实体。 有没有其他方法可以有效地实现这一目标?
谢谢。

【问题讨论】:

    标签: c# entity-framework soft-delete


    【解决方案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&lt;IDeletable&gt; Active(),然后将杂乱的东西移到使用部分:user.Roles.Active()。无法确定哪种方法更适合您的情况。

    【讨论】:

    • 感谢 SimpleVar。但是我的应用程序有数千个这样的集合,所以如果我添加更多包装器属性或使用 Active() 扩展方法将非常耗时。
    • 当您执行 this.Roles 时,您实际上是在为用户加载所有角色。过滤器应用于加载的内存实体。
    猜你喜欢
    • 1970-01-01
    • 2017-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多