有没有办法在没有数据源的情况下将LINQ查询创建为变量? [英] Is there any way to create a LINQ query as a variable without having the data source (yet)?

查看:88
本文介绍了有没有办法在没有数据源的情况下将LINQ查询创建为变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

序言:
我的核心问题与此非常相似:

Preamble:
My core question is very similar to this one: How can I write a clean Repository without exposing IQueryable to the rest of my application? which has remained unanswered. I am hoping that if I approach the problem in a different way, and ask a slightly different question, I may get a result. I will repeat some of the content from this other question to avoid requiring readers to read it for context.

问题:
我正在使用POCO实体和Entity Framework4.我试图允许在应用程序层对实体集进行复杂的即席过滤,同时尝试避免暴露IQueryable<T>超出我的存储库边界.这给我带来了一些麻烦.

Problem:
I'm working with POCO entities, and Entity Framework 4. I am trying to allow for sophisticated ad-hoc filtering of entity sets at the application layer, while simultaneously trying to avoid exposing IQueryable<T> past my repository boundary. This is leaving me with some complications.

  • 我不想在需要大量参数的存储库上创建单个大型过滤器方法,例如:

  • I do not want to create a single massive filter method on the repository that takes a huge list of parameters, such as:

IEnumerable GetFilteredCustomers(string nameFilter, string addressFilter, bool isActive, int customerId, ...)

不仅使用起来非常麻烦,而且看起来也很丑陋,特别是如果它主要是一堆null,等等.它也没有我想要的可维护性.

Not only is this extremely cumbersome to use, but it's super ugly to look at, especially if it's mostly a bunch of nulls, etc. It's also not as maintainable as I would like.

我不想在存储库上创建大量过滤方法,例如:

I do not want to create a huge set of filter methods on the repository, such as:

IEnumerable GetActiveCustomers()
IEnumerable GetCustomersByName()

此方法存在很多问题,包括需要大量方法扩展到n!,如果我希望能够以任意方式组合它们,则n是可用过滤条件的数量. (即名称为George的所有活跃客户).也很难维护.

There are a number of problems with this approach, including needing a huge list of methods which grows to n! where n is the number of available filter conditions if I want to be able to combine them in arbitrary ways. (i.e. all active customers with name George). Also highly difficult to maintain.

我不想创建操纵IEnumerable<T>的可链接方法(Fluent接口),因为最终这涉及从数据库中获取巨大的结果集并将其过滤到内存中,这不是可扩展的解决方案.

I do not want to create chainable methods (Fluent Interface) that manipulate IEnumerable<T>, because ultimately that involves bringing back a huge result set from the database and filtering it down in-memory which is not a scalable solution.

我无法创建操纵IQueryable<T>的Fluent接口,因为正如我已经说过的那样,我不想在存储库之外公开IQueryable<T>.

I can't create a Fluent Interface that manipulates IQueryable<T> because as I've already said, I don't want to expose the IQueryable<T> past the repositories.

我想避免通过传入一个充满参数的对象(而不是大参数列表)来简单地重新哈希单个大规模过滤器方法,尽管此时这可能是最丑陋的解决方案.

I'd like to avoid simply rehashing the single massive filter method by passing in an object full of parameters instead of a large parameter list, although at this point this might be the least ugly solution.

想法:
最终,我认为理想的解决方案是找到某种方法来创建不知道源的完整查询,并将其存储为参数.然后,我可以将其传递到已知源的存储库中,并将查询应用于源并返回结果.

Ideas:
Ultimately, I think an ideal solution would be discovering some way to create a full query that doesn't know the source, and store it as a parameter. I could then pass that into the repository, where the source is known, and apply the query to the source and return the results.

澄清;与如上所述简单地创建参数对象相反,我想使用原始的LINQ查询,但是以某种方式将它们存储在变量中,然后将它们应用于数据源.我怀疑必须提前知道返回类型,但是我很好地定义了它并事先知道了.

To clarify; in contrast to simply creating an object of parameters as mentioned above, I'd like to use the raw LINQ queries, but store them in a variable somehow, and apply them to a data source later. I suspect the return type would have to be known ahead of time, but I'm perfectly fine with defining that and having it known in advance.

要从另一个角度查看它,请考虑以下事项:

To view it from yet another perspective, consider the following:

IQueryable<Customer> filteredCustomers = customerRepository.GetAll()
    .Where(c => c.FirstName == "Dave")
    .Where(c => c.IsActive == true)
    .Where(c => c.HasAddress == true)
    ;

我想将三个Where子句打包为一个查询对象,与customerRepository.GetAll()完全分开,将其作为参数传递并在以后应用.

I want to package up the three Where clauses as a query object, completely separate from the customerRepository.GetAll(), pass it around as a parameter and apply it later.

推荐答案

好的.您可以编写如下方法:

Sure. You can write a method like:

public Expression<Func<Customer, bool>> GetDave()
{
    return c => c.FirstName == "Dave"
             && c.IsActive
             && c.HasAddress;
}

...以及类似的存储库方法:

...and repository methods like:

public IEnumerable<Customer> GetOneGuy(Expression<Func<Customer, bool>> criteria)
{
    return Context.Customers.Where(criteria);
}

...并致电:

var dave = Repository.GetOneGuy(this.GetDave()).Single();

这篇关于有没有办法在没有数据源的情况下将LINQ查询创建为变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆