将实体框架 IQueryable<T> 包装在操作内并应用过滤器

问题描述 投票:0回答:1

这是我在 Stack Overflow 上的第一个问题。

我正在尝试使用实体框架在 C# 中创建我自己版本的存储库模式,当我尝试将

IQueryable<T>
包装在像这样
Action<IQueryable<T>>
的操作方法中时,我偶然发现了一个问题。我的目的是允许在每个模型的存储库类中实现特定的查询逻辑。

这就是我的意思:

基础存储库:

namespace Api.Domain.Repository.Base
{
    public abstract class Repository<T> : IRepository<T> where T : BaseTable
    {
        private readonly DataContext context;
        private readonly DbSet<T> entity;

        public Repository(DataContext context)
        {
            this.context = context;
            entity = context.Set<T>();
        }

        protected IList<T> Select(Action<IQueryable<T>> filter)
        {
            if (filter == null) 
               throw new ArgumentNullException(nameof(filter));

            var query = entity.AsQueryable<T>();
            filter(query);

            return query.ToList();
        }
    }
}

具体存储库:

namespace Api.Domain.Repository
{
    public interface IAddressRepository : IRepository<Address>
    {
        IList<Address> GetMinMax(int min, int max);
    }

    public class AddressRepository : Repository<Address>, IAddressRepository
    {
        public AddressRepository(DataContext context) : base(context)
        {
        }

        public IList<Address> GetMinMax(int min, int max)
        {
            return Select(q => q
                       .Where(a => a.Id >= min && a.Id <= max));
        }
    }
}

代码编译良好,但是当我调用

GetMinMax
方法时,未应用过滤器(
.Where()
子句)。

对我做错了什么有什么想法,或者这是否可以通过实体框架实现?

c# entity-framework
1个回答
0
投票

大概应该是这样的:

protected IList<T> Select(Func<IQueryable<T>, IQueryable<T>> filter)
{
            if (filter == null) 
               throw new ArgumentNullException(nameof(filter));

            var query = entity.AsQueryable<T>();
            query = filter(query);

            return query.ToList();
}

LINQ 的工作方式类似于装饰器、过滤器和其他操作,返回应用了过滤器的新对象。原来的 IQueryable 永远不会改变。

© www.soinside.com 2019 - 2024. All rights reserved.