【问题标题】:Generic Repository Filter Child Properties通用存储库过滤器子属性
【发布时间】:2016-12-19 15:28:12
【问题描述】:

我正在使用通用存储库来查询我的数据库here。我所有的实体都继承了一个具有属性Active 的基类,当用户删除它时,我将Active 设置为false。我现在面临的问题是,虽然下面的代码适用于主要实体,但我无法弄清楚如何只返回 Active 子活动。

我尝试过使用动态 linq,但没有成功。除了在子实体上使用最明显的 linq 之外,还有什么方法可以做到这一点?

 public virtual TEntity GetById(object id,
        Expression<Func<TEntity, bool>> filter = null,
        string includeProperties = "")
    {
        IQueryable<TEntity> query = DbSet;

        if (filter != null)
        {
            query = query.Where(filter);
        }
        if (includeProperties.Length > 0)
        {
            query = includeProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
                .Aggregate(query, (current, includeProperty) => current.Include(includeProperty));
        }
        else
        {
            return DbSet.Find(id);
        }

        if (query.Any())
        {
            return query.First();
        }
        return query.First();
    }

【问题讨论】:

  • 您可以尝试使用反射来获取实体的子实体,然后使用动态 LINQ 应用其他过滤器。从未使用过动态 LINQ,因此无法给出完整的答案,但如果您真的想避免调用者进行过滤,这似乎是前进的方向
  • 停止创建通用存储库!

标签: c# asp.net-mvc entity-framework linq


【解决方案1】:

您应该为此创建过滤器 (EntityFramework.Filters):

public interface IActive
{
    public bool Active {get;set;}
}

public class MyClass : IActive
{
    public int Id {get;set;}
    public bool Active {get;set;}
}

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{   
    modelBuilder.Conventions
       .Add(FilterConvention.Create<IActive, bool>("MyFilter", (entity, Active) => entity.Active);
}

用法:

var filter = context.EnableFilter("MyFilter");
filter.SetParameter("Active", true);

var item = GetById(1);
//now inside GetById method 'item' and all it's children will be filtered with "Active == true" condition

context.DisableFilter("MyFilter");

【讨论】:

    【解决方案2】:

    选项之一:

    public virtual TEntity GetById(object id,
            Expression<Func<TEntity, bool>> filter = null,
            string includeProperties = "")
        {
            IQueryable<TEntity> query = GetActive();
    
            if (filter != null)
            {
                query = query.Where(filter);
            }
            if (includeProperties.Length > 0)
            {
                query = includeProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
                    .Aggregate(query, (current, includeProperty) => current.Include(includeProperty));
            }
            else
            {
                return DbSet.Find(id);
            }
    
            if (query.Any())
            {
                return query.First();
            }
            return query.First();
        }
    
    public virtual IQueryable<TEntity> GetActive()
    {
        return 
            DbSet.Where(a => a.Active);
    }
    

    【讨论】:

    • 我们已经能够过滤父实体但不能过滤子实体。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多