【问题标题】:Linq: how to exclude condition if parameter is nullLinq:如果参数为空,如何排除条件
【发布时间】:2011-09-15 22:53:48
【问题描述】:

我有一些表和以下查询条件:如果参数A为空,则全部取走,如果不是,则在查询中使用它。我知道如何分两步做到这一点:

List<O> list = null;
if (A = null)
{
    list = context.Obj.Select(o => o).ToList();
}
else
{
    list = context.Obj.Where(o.A == A).ToList();
}

是否可以与一个查询相同? 谢谢

【问题讨论】:

  • 我认为你不需要那里的Select()
  • 我希望你的意思是A == null! (C# 应该阻止它编译,但最好确保发布的代码采用正确的可编译形式。批评发布的代码很重要,因为 已经编译 [但没有按预期工作]在某些语言中。)

标签: c# sql linq


【解决方案1】:

怎么样:

list = context.Obj.Where(o => A == null || o.A == A)
                  .ToList();

您可以在一个查询中执行此操作,但仍使用条件:

IEnumerable<O> query = context.Obj;
if (A != null)
{
    query = query.Where(o => o.A == A);
}
var list = query.ToList();

或者您可以使用条件运算符将查询放在单个语句中:

var query = A is null ? context.Obj : context.Obj.Where(o => o.A == A);
var list = query.ToList();

我个人会建议后一种选择,因为它们不要求 LINQ 提供程序能够在 A 为空的情况下优化过滤器。 (我希望大多数优秀的 LINQ 提供程序/数据库能够做到这一点,但我通常会避免在不需要时指定过滤器。)

【讨论】:

  • 这样,A == null 的条件将针对集合中的每个项目进行评估,虽然更具可读性,但我认为它并不完全正确。
  • @AS-CII,不一定。 LINQ to 对象就是这种情况。但这个查询看起来像 LINQ to SQL 或类似的东西。
  • @svick - 好点。无论如何,我认为这不应该成为Where 子句的一部分。我的意思是,客户端变量的可空性检查对查询有意义吗?
  • @AS-CII:LINQ 到 SQL 的转换可能会注意到这是一个常量“真”值,并且不会发送该值,甚至不会发送任何 where 子句。我并不是说这特别好 - 只是它是被要求的。
  • 虽然这个答案可能是正确的,但根本没有用。
【解决方案2】:

我选择了

var list = context.Obj.Where(o => A.HasValue ? o.a == A : true);

【讨论】:

  • 解决了我的问题。当控制器操作的参数为空时。
  • 另请注意,这仅在 ANullable&lt;T&gt; 而不是(例如)string 时才有效。我们不知道这里的类型...
  • 啊,好点子,谢谢@JonSkeet!
【解决方案3】:

我可能会这样写查询:

IQueryable<O> query = context.Obj;
if (A != null)
    query = query.Where(o => o.A == A);
var list = query.ToList()

这不是一种表达方式,但我认为它很有可读性。

此外,此代码假定 context.ObjIQueryable&lt;O&gt;(例如,您使用的是 LINQ to SQL)。如果不是这种情况,请使用IEnumerable&lt;O&gt;

【讨论】:

    【解决方案4】:

    试试

    context.Obj.Where(a => A != null && a.A == A).ToList()
    

    应该都很好。如果 A 为 null,则 'a.A == A' 将被忽略。

    【讨论】:

    • 如果 A 为空,那么这将给出 no 结果而不是 all 结果。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-28
    • 1970-01-01
    • 2017-06-02
    • 1970-01-01
    • 2014-08-06
    • 1970-01-01
    相关资源
    最近更新 更多