前言:
我的核心问题与此非常相似:如何编写一个干净的存储库而不将 IQueryable 暴露给应用程序的其余部分? https://stackoverflow.com/questions/1030992/how-can-i-write-a-clean-repository-without-exposing-iqueryable-to-the-rest-of-my至今仍未得到答复。我希望如果我以不同的方式处理这个问题,并提出一个稍微不同的问题,我可能会得到结果。我将重复另一个问题中的一些内容,以避免要求读者阅读它以了解上下文。
Problem:
我正在使用 POCO 实体和实体框架 4。我试图允许在应用程序层对实体集进行复杂的临时过滤,同时尝试避免暴露IQueryable<T>
超出了我的存储库边界。这给我留下了一些麻烦。
-
我不想在存储库上创建一个需要大量参数的大型过滤方法,例如:
IEnumerable GetFilteredCustomers(string nameFilter, string addressFilter, bool isActive, int customerId, ...)
这不仅使用起来非常麻烦,而且看起来也非常难看,特别是如果它主要是一堆空值等。它也不像我想要的那样可维护。
-
我不想在存储库上创建大量过滤方法,例如:
IEnumerable GetActiveCustomers()
IEnumerable GetCustomersByName()
这种方法存在许多问题,包括需要大量的方法,这些方法会增长到n!
其中 n 是可用过滤条件的数量(如果我希望能够以任意方式组合它们)。 (即所有名为 George 的活跃客户)。维护起来也非常困难。
我不想创建可链接的方法(流畅的接口)来操作IEnumerable<T>
,因为最终涉及从数据库带回巨大的结果集并将其过滤到内存中,这不是一个可扩展的解决方案。
我无法创建一个流畅的界面来操作IQueryable<T>
因为正如我已经说过的,我不想暴露IQueryable<T>
经过存储库。
我想避免通过传入一个充满参数的对象而不是一个大的参数列表来简单地重新哈希单个大规模过滤器方法,尽管此时这可能是最不丑陋的解决方案。
Ideas:
最终,我认为理想的解决方案是发现某种方法来创建不知道源的完整查询,并将其存储为参数。然后,我可以将其传递到源已知的存储库中,并将查询应用于源并返回结果。
澄清;与如上所述简单地创建参数对象相反,我想使用原始 LINQ 查询,但以某种方式将它们存储在变量中,然后将它们应用到数据源。我怀疑返回类型必须提前知道,但我完全可以定义它并提前知道它。
要从另一个角度来看它,请考虑以下因素:
IQueryable<Customer> filteredCustomers = customerRepository.GetAll()
.Where(c => c.FirstName == "Dave")
.Where(c => c.IsActive == true)
.Where(c => c.HasAddress == true)
;
我想将三个Where子句打包为一个查询对象,与customerRepository.GetAll()完全分开,将其作为参数传递并稍后应用。
当然。您可以编写如下方法:
public Expression<Func<Customer, bool>> GetDave()
{
return c => c.FirstName == "Dave"
&& c.IsActive
&& c.HasAddress;
}
...以及存储库方法,例如:
public IEnumerable<Customer> GetOneGuy(Expression<Func<Customer, bool>> criteria)
{
return Context.Customers.Where(criteria);
}
...并致电:
var dave = Repository.GetOneGuy(this.GetDave()).Single();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)