这是我在 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()
子句)。
对我做错了什么有什么想法,或者这是否可以通过实体框架实现?
大概应该是这样的:
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 永远不会改变。