Mir*_*Mir 5 c# linq asp.net linq-to-entities entity-framework-4
序言:
我的核心问题与此非常类似:如何在不将IQueryable暴露给我的应用程序的其余部分的情况下编写一个干净的存储库?一直没有答案.我希望如果我以不同的方式解决问题,并提出一个稍微不同的问题,我可能会得到一个结果.我将重复这个问题的一些内容,以避免要求读者阅读上下文.
问题:
我正在使用POCO实体和实体框架4.我试图在应用层允许对实体集进行复杂的ad-hoc过滤,同时试图避免暴露在IQueryable<T>我的存储库边界之外.这让我有些困难.
我不想在存储库上创建一个带有大量参数的单个大规模过滤器方法,例如:
IEnumerable GetFilteredCustomers(string nameFilter, string addressFilter, bool isActive, int customerId, ...)
Run Code Online (Sandbox Code Playgroud)
这不仅非常麻烦,而且看起来非常难看,特别是如果它主要是一堆零点等等.它也不像我想的那样可维护.
我不想在存储库上创建大量的过滤方法,例如:
IEnumerable GetActiveCustomers()
IEnumerable GetCustomersByName()
Run Code Online (Sandbox Code Playgroud)
这种方法存在许多问题,包括需要大量的方法列表,n!如果我希望能够以任意方式组合它们,那么n就是可用过滤条件的数量.(即所有名为George的活跃客户).也很难维护.
我不想创建可操作的可链接方法(Fluent Interface)IEnumerable<T>,因为最终需要从数据库中返回一个巨大的结果集并将其过滤到内存中,这不是一个可扩展的解决方案.
我无法创建一个操作的Fluent界面,IQueryable<T>因为正如我已经说过的,我不想暴露IQueryable<T>过去的存储库.
我想避免简单地通过传入一个充满参数而不是大参数列表的对象来重复单个大规模过滤方法,尽管此时这可能是最不丑的解决方案.
想法:
最终,我认为一个理想的解决方案是发现一些方法来创建一个不知道源的完整查询,并将其存储为参数.然后我可以将其传递到知道源的存储库中,并将查询应用于源并返回结果.
澄清; 与上面提到的简单地创建参数对象相反,我想使用原始LINQ查询,但是以某种方式将它们存储在变量中,并稍后将它们应用于数据源.我怀疑返回类型必须提前知道,但我完全可以定义并事先知道它.
要从另一个角度查看它,请考虑以下事项:
IQueryable<Customer> filteredCustomers = customerRepository.GetAll()
.Where(c => c.FirstName == "Dave")
.Where(c => c.IsActive == true)
.Where(c => c.HasAddress == true)
;
Run Code Online (Sandbox Code Playgroud)
我想将三个Where子句打包为一个查询对象,与customerRepository.GetAll()完全分开,将其作为参数传递并稍后应用.
Cra*_*ntz 10
当然.您可以编写如下方法:
public Expression<Func<Customer, bool>> GetDave()
{
return c => c.FirstName == "Dave"
&& c.IsActive
&& c.HasAddress;
}
Run Code Online (Sandbox Code Playgroud)
...和存储库方法如:
public IEnumerable<Customer> GetOneGuy(Expression<Func<Customer, bool>> criteria)
{
return Context.Customers.Where(criteria);
}
Run Code Online (Sandbox Code Playgroud)
...并致电:
var dave = Repository.GetOneGuy(this.GetDave()).Single();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2286 次 |
| 最近记录: |