在LINQ到Entities Where表达式中如何构建逻辑提供的逻辑? [英] How can I build logic upon supplied logic in a LINQ-to-Entities Where expression?
问题描述
。如果指定了一个字符串值,那么
子句,如: IQueryable&Foo> query = Foos.AsQueryable()
if(!string.IsNullOrWhitespace(nameFilter))query = query.Where(x => x.Name == name);
if(!string.IsNullOrWhitespace(addressFilter)!= null)query = query.Where(x => x.Address == addressFilter);
if(!string.IsNullOrWhitespace(cityFilter)!= null)query = query.Where(x => x.City == cityFilter);
// ...
我想清理它,并避免重复过滤器。我以为我可以创建一个扩展方法:
public static IQueryable< T>其中,EqualIfSpecified< T>(
此IQueryable< T>查询,
表达式< Func< T,string>> fieldDelegate,
string filterValue)
{
返回字符串.IsNullOrWhiteSpace(filterValue)
?查询
:query.Where(x => fieldDelegate(x)== filterValue); //无效,请参阅下面的问题
}
所以我可以改变我的代码到:
IQueryable&Foo> query = Foos.AsQueryable()
.WhereEqualIfSpecified(x => x.Name,nameFilter)
.WhereEqualIfSpecified(x => x.Address,addressFilter)
.WhereEqualIfSpecified(x = > x.City,cityFilter)
// ...
;但是我发现在 WhereEqualIfSpecified
中,上面的方法, fieldDelegate
必须被编译为一个 Func()
被调用对实体源,这废止了点执行这些步骤,这将在我的原始代码中的数据库中执行。
我错过了如何创建新的来自 fieldDelegate
的表达式
可以进行比较,而不仅仅是返回字符串值。这种方法是否有效?如何在 WhereEqualIfSpecified
中使必要的表达式
允许LINQ到实体稍后执行?
解决方案这里要做的是组合表达式。与代表不同,表达方式有点复杂。 这里是如何撰写表达式的一个实现。一旦你有这个 Compose
方法,你可以写你的扩展方法为:
public static IQueryable< T> WhereEqualIfSpecified< T>(
this IQueryable< T>查询
表达式&FunC< T,string>> fieldExpression,
string filterValue)
{
返回字符串.IsNullOrWhiteSpace(filterValue)
?查询
:query.Where(fieldExpression.Compose(value => value == filterValue);
}
I often come across, in LINQ for Entity Framework, a pattern where I add a .Where
clause if a string value is specified, like:
IQueryable<Foo> query = Foos.AsQueryable()
if (!string.IsNullOrWhitespace(nameFilter)) query = query.Where(x => x.Name == name);
if (!string.IsNullOrWhitespace(addressFilter) != null) query = query.Where(x => x.Address == addressFilter );
if (!string.IsNullOrWhitespace(cityFilter) != null) query = query.Where(x => x.City == cityFilter );
// ...
I wanted to clean this up and avoid repeating the filter. I thought I could create an extension method:
public static IQueryable<T> WhereEqualIfSpecified<T>(
this IQueryable<T> query,
Expression<Func<T, string>> fieldDelegate,
string filterValue)
{
return string.IsNullOrWhiteSpace(filterValue)
? query
: query.Where(x => fieldDelegate(x) == filterValue); // not valid, see question below
}
So that I can instead change my code to:
IQueryable<Foo> query = Foos.AsQueryable()
.WhereEqualIfSpecified(x => x.Name, nameFilter)
.WhereEqualIfSpecified(x => x.Address, addressFilter)
.WhereEqualIfSpecified(x => x.City, cityFilter)
// ...
;
But I found that, in the WhereEqualIfSpecified
method above, fieldDelegate
must be compiled to a Func()
to be invoked against the entity source, which ruins the point of doing these steps, which would be executed in the database in my original code.
I am missing the last step of how to create a new Expression
from fieldDelegate
that can do a comparison, rather than just returning the string value. Will this approach work? How do I make the necessary Expression
in WhereEqualIfSpecified
to allow LINQ-to-Entities to execute it later?
解决方案 What you're trying to do here is to compose expressions. Expressions, unlike delegates, are a bit tricker to compose. Here is one implementation of how to compose expressions. Once you have that Compose
method you can write your extension method as:
public static IQueryable<T> WhereEqualIfSpecified<T>(
this IQueryable<T> query,
Expression<Func<T, string>> fieldExpression,
string filterValue)
{
return string.IsNullOrWhiteSpace(filterValue)
? query
: query.Where(fieldExpression.Compose(value => value == filterValue);
}
这篇关于在LINQ到Entities Where表达式中如何构建逻辑提供的逻辑?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!