所以,我已经阅读了所有关于是否将IQueryable暴露给你项目的其余部分的问题所在的问题(见这里和这里),我最终决定我不想要将IQueryable暴露给我的模型以外的任何东西.因为IQueryable与某些持久性实现有关,所以我不喜欢将自己锁定在其中的想法.同样,我不确定我对调用链中的类进一步修改不在存储库中的实际查询的感觉有多好.
那么,有没有人有任何关于如何编写一个干净简洁的存储库而不这样做的建议?我看到的一个问题是,我的存储库将从大量方法中爆炸,我需要过滤掉我的查询.
有一堆:
IEnumerable GetProductsSinceDate(DateTime date);
IEnumberable GetProductsByName(string name);
IEnumberable GetProductsByID(int ID);
Run Code Online (Sandbox Code Playgroud)
如果我允许传递IQueryable,我可以很容易地拥有一个看起来像这样的通用存储库:
public interface IRepository<T> where T : class
{
T GetById(int id);
IQueryable<T> GetAll();
void InsertOnSubmit(T entity);
void DeleteOnSubmit(T entity);
void SubmitChanges();
}
Run Code Online (Sandbox Code Playgroud)
但是,如果你没有使用IQueryable,那么像GetAll()这样的方法并不实用,因为延迟评估不会发生.我不想只返回10,000条记录,以后再使用其中的10条.
这是什么答案?在Conery的MVC店面中,他创建了另一个名为"服务"层的层,该层从存储库接收了IQueryable结果,并负责应用各种过滤器.
这是我应该做的,或类似的东西?让我的存储库返回IQueryable但是通过将其隐藏在一堆过滤器类(如GetProductByName)后限制对它的访问,这将返回像IList或IEnumerable这样的具体类型?
我有这个想法来创建一个执行不同类型操作的 IQueryables 的“列表”。
所以基本上:
var query1 = Enumerable.Empty<Person>().AsQueryable().Where(e => e.Name == "Ronald");
var query2 = Enumerable.Empty<Person>().AsQueryable().Where(e => e.Age == 43);
var query3 = Enumerable.Empty<Person>().AsQueryable().Select(e => e.EyeColor);
var listOfQueries = new List<IQueryable<Person>
{
query1,
query2,
query3
};
Run Code Online (Sandbox Code Playgroud)
现在,我也有这个充满“Persons”的 DbSet,我想“应用”针对该 DbSet 的所有查询。我该怎么做呢?有可能吗?
更新的示例:
var personQueryFactory = new PersonQueryFactory();
var personQueryByFirstname = personQueryFactory.CreateQueryByFirstname("Ronald"); //Query by Firstname.
var personQueryByAge = personQueryFactory.CreateQueryByAge(42); //Query by age.
var personQueryByHasChildWithAgeOver = personQueryFactory.CreateQueryByChildAgeOver(25); //Query using a "join" to the child-relationship.
var personQuerySkip = personQueryFactory.Take(5); //Only get the 5 first …Run Code Online (Sandbox Code Playgroud)