【问题标题】:Linq FirstOrDefaultLinq 优先或默认
【发布时间】:2012-01-16 21:52:34
【问题描述】:

我有以下 LINQ 查询:

    Manager mngr = (from tr in DataContext.Manager
                    where tr.Name = "Jones").FirstOrDefault();

如何检查查询是否返回了 1 条记录 因为我不能做 .Count 来获得计数。

【问题讨论】:

  • 查看 FirstOrDefault 方法的文档。如果没有结果,它将返回数据类型的默认值。如果必须 不超过 1 条记录通过查询条件,请改用 SingleOrDefault。

标签: linq


【解决方案1】:

首先,这不是一个有效的查询。当您使用查询语法 (from blah in blah ...) 时,您必须有一个 select 子句。它应该更像:

var manager =
    (from n in DataContext.Manager
    where n.Name == "Jones"
    select n).FirstOrDefault();

要回答您的问题,对您的查询调用FirstOrDefault() 将返回查询的第一个结果或该类型的默认值(在这种情况下很可能是null)。对于您的目标,这不是一个充分的用途,因为查询可能包含多个结果。

如果您希望验证查询是否只返回一个结果,您应该改用SingleOrDefault() 方法。它将返回查询产生的一项,如果它为空则返回默认值null,如果有多个项则抛出异常。

如果您不想抛出异常,将前两个结果放入列表并验证您是否只有一个可能更容易。

var managers =
    (from m in DataContext.Manager
    where m.Name == "Jones"
    select m).Take(2).ToList();
if (managers.Count == 1)
{
    // success!
    var manager = managers.First();
    // do something with manager
}
else
{
    // error
}

【讨论】:

  • 我的做法是说 if(mngr != null){ .. 我们知道我们至少获得了 1 条记录}
  • 还有一个 .Single() 可以检查您有准确一条记录
  • -1 建议将结果放入列表并计数将是一个适当的解决方案。在大型结果集或必须遍历大型表以获取所有数据的情况下这样做会非常糟糕。 First 和 Single 都进行了您的建议无法复制的后端优化。
【解决方案2】:

如果要统计记录,统计查询的结果没有 FirstOrDefault。

var mngr = (from tr in DataContext.Manager
                where tr.ID = "2323")
if(mngr.Count() == 0)
   ....
else
   Manager manager = mngr.First(); //No need for default since we know we have a record.

你仍然可以在 mngr 上先运行或默认运行以获取特定的管理器。

【讨论】:

    【解决方案3】:

    您正在为where 条件使用ID,我认为您应该已经保证此查询只返回一个结果。

    如果您的问题没有结果,请检查FirstOrDefault() 的使用情况,来自MSDN title

                int[] numbers = { };
                int first = numbers.FirstOrDefault();
                Console.WriteLine(first);
    
                /*
                 This code produces the following output:
    
                 0
                */
    

    【讨论】:

      【解决方案4】:

      您可以使用SingleOrDefault 扩展方法来表示查询只应返回一个结果。

      Manager manager = (from tr in DataContext.Manager 
                         where tr.ID = "2323").SingleOrDefault();
      

      但是它并不能告诉你你得到了 0 个结果还是超过 1 个。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-09-25
        • 1970-01-01
        • 2013-04-05
        • 1970-01-01
        • 1970-01-01
        • 2013-11-04
        • 2017-07-07
        • 2020-02-10
        相关资源
        最近更新 更多