LINQ:何时使用SingleOrDefault与FirstOrDefault()以及过滤标准

考虑IEnumerable扩展方法SingleOrDefault()FirstOrDefault()

MSDN文档SingleOrDefault

返回序列的唯一元素,如果序列为空,则返回默认值; 如果序列中有多个元素,则此方法会引发异常。

而来自MSDN的FirstOrDefault (大概在使用OrderBy()OrderByDescending()或根本不使用时),

返回序列的第一个元素

考虑一些示例查询,使用这两种方法时并不总是很清楚:

var someCust = db.Customers
.SingleOrDefault(c=>c.ID == 5); //unlikely(?) to be more than one, but technically COULD BE

var bobbyCust = db.Customers
.FirstOrDefault(c=>c.FirstName == "Bobby"); //clearly could be one or many, so use First?

var latestCust = db.Customers
.OrderByDescending(x=> x.CreatedOn)
.FirstOrDefault();//Single or First, or does it matter?

在您的LINQ查询中决定使用SingleOrDefault()FirstOrDefault()时, 您遵循或建议了哪些约定


无论何时使用SingleOrDefault ,都明确指出查询最多SingleOrDefault得到一个结果。 另一方面,当使用FirstOrDefault时,查询可以返回任意数量的结果,但是您声明您只需要第一个结果。

我个人发现语义非常不同,并根据预期的结果使用适当的语义,提高了可读性。


如果结果集返回0个记录:

  • SingleOrDefault返回类型的默认值(例如,默认值为int)
  • FirstOrDefault返回该类型的默认值
  • 如果结果集返回1记录:

  • SingleOrDefault返回该记录
  • FirstOrDefault返回该记录
  • 如果结果集返回许多记录:

  • SingleOrDefault引发异常
  • FirstOrDefault返回第一条记录
  • 结论:

    如果要在结果集包含许多记录时抛出异常,请使用SingleOrDefault

    如果您始终需要1条记录,而不管结果集包含什么内容,请使用FirstOrDefault


  • 语义上的差异
  • 性能差异
  • 两者之间。

    语义差异:

  • FirstOrDefault返回可能为多个的第一项(如果不存在,则返回默认值)。
  • SingleOrDefault假设有一个项目并返回它(或者如果不存在则返回默认值)。 多个项目违反合同,会引发异常。
  • 性能差异

  • FirstOrDefault通常更快,它会迭代直到找到元素,并且只有当它找不到时才迭代整个枚举。 在很多情况下,找到一件物品的可能性很大。

  • SingleOrDefault需要检查是否只有一个元素,因此总是迭代整个枚举。 确切地说,它迭代直到找到第二个元素并引发异常。 但在大多数情况下,没有第二个因素。

  • 结论

  • 如果您不在意有多少物品无法检查唯一性(例如,在一个非常大的集合中),请使用FirstOrDefault 。 当您在将项目添加到集合时检查唯一性时,在搜索这些项目时再次检查它可能太昂贵。

  • 如果您不必关心性能太多,并希望确保单个项目的假设对读者是清楚的并在运行时进行检查,则使用SingleOrDefault

  • 在实践中,即使在您假定单个项目的情况下,您也经常使用First / FirstOrDefault来提高性能。 您应该还记得Single / SingleOrDefault可以提高可读性(因为它表示单个项目的假设)和稳定性(因为它会检查它)并适当地使用它。

    链接地址: http://www.djcxy.com/p/34279.html

    上一篇: LINQ: When to use SingleOrDefault vs. FirstOrDefault() with filtering criteria

    下一篇: LINQ order by a number sequence