gpt4 book ai didi

c# - Linq 用 OR 动态追加 Where 子句

转载 作者:行者123 更新时间:2023-11-30 14:29:15 26 4
gpt4 key购买 nike

我一直在尝试构建一个带有动态添加的 where 子句的 linq 查询。我有一个带有一堆复选框的网页,这些复选框被选中以对应于您要搜索的字段:

enter image description here

到目前为止,我有以下内容:

//This calls a select from table to construct the query which the where clauses will be added to
IQueryable<AutoCompleteRestultDto> query = GetAutocompleteResults();

if (FirstName == true || AllFields == true)
{
Expression<Func<AutoCompleteRestultDto, bool>> firstNameFilter = c => terms.Any(t => c.FirstName.ToLower().Contains(t.ToLower()));
query = query.Where(firstNameFilter);
}
if (LastName == true || AllFields == true)
{
Expression<Func<AutoCompleteRestultDto, bool>> lastNameFilter = c => terms.Any(t => c.LastName.ToLower().Contains(t.ToLower()));
query = query.Where(lastNameFilter);
}
if (KnownAs == true || AllFields == true)
{
Expression<Func<AutoCompleteRestultDto, bool>> knownAsFilter = c => terms.Any(t => c.KnownAs.ToLower().Contains(t.ToLower()));
query = query.Where(knownAsFilter);
}
// etc.

return query
.Select(c => new ContactAutoCompleteModel
{
label = c.FirstName + " " + c.LastName
})
.Take(15)
.OrderBy(d => d.label)
.ToList();

问题是这个解决方案要求附加的所有表达式同时为真,即:where(clause1 AND clause2 AND clause3)

无法弄清楚如何将其更改为 OR 子句,即:where(clause1 OR clause2 OR clause3)

最佳答案

您正在将 Enumerable.Where 调用链接到您发布的代码中。这就是您获得 AND 效果的原因。下面是使用谓词而不是表达式的 PredicateBuilder 偷猎。

  public static class PredicateExtensions
{
public static Predicate<T> Or<T> (this Predicate<T> p1, Predicate<T> p2)
{
return obj => p1(obj) || p2(obj);
}

public static Predicate<T> And<T> (this Predicate<T> p1, Predicate<T> p2)
{
return obj => p1(obj) && p2(obj);
}
public static Predicate<T> False<T> () { return obj => false; }
public static Predicate<T> True<T> () { return obj => true; }

public static Predicate<T> OrAll<T> (IEnumerable<Predicate<T>> conditions)
{
Predicate<T> result = PredicateExtensions.False<T>();
foreach (Predicate<T> cond in conditions)
result = result.Or<T>(cond);
return result;
}

public static Predicate<T> AndAll<T> (IEnumerable<Predicate<T>> conditions)
{
Predicate<T> result = PredicateExtensions.True<T>();
foreach (Predicate<T> cond in conditions)
result = result.And<T>(cond);
return result;
}
}

您可以像这样使用 enumerable ,在某些条件下自定义(先验)可枚举的谓词:

Predicate<AutoCompleteRestultDto> firstNamePredicate = 
c => terms.Any(t => c.FirstName.ToLower().Contains(t.ToLower()));
Predicate<AutoCompleteRestultDto> lastNamePredicate =
c => terms.Any(t => c.LastName.ToLower().Contains(t.ToLower()));
Predicate<AutoCompleteRestultDto> knownAsPredicate =
c => terms.Any(t => c.KnownAs.ToLower().Contains(t.ToLower()));
var all = new Predicate<AutoCompleteRestultDto>[] {
firstNamePredicate,
knownAsPredicate,
lastNamePredicate };
//
var items = query.Where(a => PredicateExtensions.OrAll(all)(a)).ToList();
items = query.Where(a => PredicateExtensions.AndAll(all)(a)).ToList();

或像您一样逐步添加它们:

Predicate<AutoCompleteRestultDto> orResultPredicate = 
PredicateExtensions.False<AutoCompleteRestultDto>();
if (FirstName == true || AllFields == true) {
orResultPredicate=orResultPredicate.Or(firstNamePredicate); }
if (LastName == true || AllFields == true) {
orResultPredicate = orResultPredicate.Or(lastNamePredicate); }
if (KnownAs == true || AllFields == true) {
orResultPredicate = orResultPredicate.Or(knownAsPredicate); }
Func<AutoCompleteRestultDto, bool> funcOr = c => orResultPredicate(c);
//
IQueryable<AutoCompleteRestultDto> query; // initialized already
var items = query.Where(funcOr).ToList();

关于c# - Linq 用 OR 动态追加 Where 子句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26542555/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com