Conditional Linq

本文关键字:Linq Conditional | 更新日期: 2023-09-27 18:25:07

我有两个条件,它们可能都被设置,也可能只是其中之一。如果两者都设置为一个值,则应触发将AND作为布尔运算符的linq-where语句,否则linq-where声明应仅包括基于设置条件的筛选器。

例如:

两个条件都设置为:linq。其中(condition1&condition2)。。。

仅条件1集:linq。其中(条件1)。。

仅条件2集:linq。其中(条件2)。。

这是不允许的:linq。其中(condition1||condition2)因为过滤应该是非常准确的

现在我的问题是如何编写一个考虑所有这些需求的linq语句?提前感谢

编辑:

谓词可能是这样的:x=>x>10或x=>x=="Hello"或x=>x+2==3…任何适合where语句的表达式。

我得到条件/谓词,我自己不创建它们

关于谓词,我指的是数学中的谓词,而不是c#中的类。

没有太多的代码可以发布,因为我不知道如何在ONE linq语句中做到这一点

结果必须是一个处理所有这些的linq语句。

我是新来的,我不知道该怎么写,所以我希望你能帮我。

如果你不喜欢它,不要投反对票,它就会过去,有人会帮我的。

第2版:

我是认真的。不多不少:

method<T> filterList(ienumerable<T> linq, Predicate<T> p1, Predicate<T> p2)
{
  return linq.Where(only p1 or only p2 or p1 && p2)
}

Conditional Linq

这就是monad的美妙之处-您不必一步完成所有操作。

// bool? flag1
// bool? flag2
// IQueryable<something> collection

if(flag1.HasValue)
    collection = collection.Where(x => x.Flag1 == flag1);
if(flag2.HasValue)
    collection = collection.Where(x => x.Flag2 == flag2);
//...

编辑:如果你想在一个LINQ语句中完成它,你需要通过调用谓词来完成一些技巧:

public IEnumerable<T> FilterList<T>(IEnumerable<T> collection, Predicate<T> p1, Predicate<T> p2)
{
    return collection.Where(x =>
        (p1 == null || p1.Invoke(x)) &&
        (p2 == null || p2.Invoke(x))
    );
}

如果两者都未设置,你不会说该怎么办,我假设在这种情况下根本没有过滤我假设所说的"没有值",例如p1为null。我不能100%确定你所说的ONE linq语句是什么意思,但我认为以下至少有一个可以满足你的需求。

在所有情况下,我说的基本上是[用始终为真的谓词和谓词替换空谓词]

解决方案1

return linq.Where(x => p1 != null ? p1(x) : true).Where(x => p2 != null ? p2(x) : true);

解决方案2

var p1a = p1 ?? (x => true);
var p2a = p2 ?? (x => true);
return linq.Where(x => p1a(x) && p2a(x));

解决方案3

return linq.Where(x => (p1 ?? (y=>true))(x) && (p2 ?? (z=>true))(x));

如果使用第三方PredicateBuilder,则可以迭代构建or过滤器和and过滤器。

示例

  var predicate = PredicateBuilder.False<Product>();
  foreach (string keyword in keywords)
  {
    string temp = keyword;
    predicate = predicate.Or (p => p.Description.Contains (temp));
  }
  return dataContext.Products.Where (predicate);