ric*_*eym 5 c# linq linq-to-sql predicatebuilder
我们有一个使用LINQ to SQL的项目,为此我需要重写几个搜索页面以允许客户端选择是否要执行和/或搜索.
我虽然使用PredicateBuilder重做LINQ查询,但我认为这个工作得很好.我实际上有一个包含我的谓词的类,例如:
internal static Expression<Func<Job, bool>> Description(string term)
{
return p => p.Description.Contains(term);
}
Run Code Online (Sandbox Code Playgroud)
要执行搜索,我正在执行此操作(为简洁起见,省略了一些代码):
public Expression<Func<Job, bool>> ToLinqExpression()
{
var predicates = new List<Expression<Func<Job, bool>>>();
// build up predicates here
if (SearchType == SearchType.And)
{
query = PredicateBuilder.True<Job>();
}
else
{
query = PredicateBuilder.False<Job>();
}
foreach (var predicate in predicates)
{
if (SearchType == SearchType.And)
{
query = query.And(predicate);
}
else
{
query = query.Or(predicate);
}
}
return query;
}
Run Code Online (Sandbox Code Playgroud)
虽然我对此感到满意,但我有两个顾虑:
为了解决第2点,我想我可以通过简单地重写我的表达式来做到这一点,例如:
internal static Expression<Func<Job, bool>> Description(string term, bool invert)
{
if (invert)
{
return p => !p.Description.Contains(term);
}
else
{
return p => p.Description.Contains(term);
}
}
Run Code Online (Sandbox Code Playgroud)
然而,这感觉有点像一个kludge,这通常意味着那里有一个更好的解决方案.任何人都可以推荐如何改善这一点?我知道动态LINQ,但我真的不想失去LINQ的强类型.
如果您正在寻找更少的线路,您可以使用三元运算符替换if/else:
query = SearchType == SearchType.And ? PredicateBuilder.True<Job>() : PredicateBuilder.False<Job>();
foreach (var predicate in predicates)
{
query = SearchType == SearchType.And ? query.And(predicate) : query.Or(predicate);
}
Run Code Online (Sandbox Code Playgroud)
对于该'and not' / 'or not'部分,!操作员应该做到这一点.
PD:您是否测试过该foreach部件是否正确设置谓词?,据我所知,您正在构建将在稍后的时间点执行的表达式,因此您可能只有最终设置谓词的文字参考迭代,这就是为什么你必须使用临时变量来保存每次迭代的值.
编辑: 如果你想否定一个程序性的表达式,这是一个棘手的,你可以尝试类似的东西:
internal static Expression<Func<Job, bool>> Description(string term, bool invert)
{
return NegateExp<Func<Job, bool>>(p => p.Description.Contains(term), invert);
}
Run Code Online (Sandbox Code Playgroud)
而NegateExp方法将类似于:
public static Expression<TDelegate> NegateExp<TDelegate>(Expression<TDelegate> expression, bool inverse)
{
if (inverse)
{
return Expression.Lambda<TDelegate>(Expression.Not(expression.Body), expression.Parameters);
}
return expression;
}
Run Code Online (Sandbox Code Playgroud)
您可以查看此问题以获取更多示例是否有任何方法可以否定谓词?
| 归档时间: |
|
| 查看次数: |
7922 次 |
| 最近记录: |