实体框架4 Single() vs First() vs FirstOrDefault()

我花了很多时间比较不同的方法来查询一个项目,以及何时使用每个项目。

是否有人有一个链接,比较所有这些,或一个快速解释为什么你会使用其中之一,而不是其他?还有我不知道的操作员吗?

谢谢你。

85218 次浏览

其实非常简单: Single返回一个项目,如果没有或者有多个项目,则抛出一个异常。First将返回第一个项目或在没有项目时抛出。当没有项时,FirstOrDefault将返回第一个项或默认值(如果给定类型是引用类型,则为 null)。

这是 API 应该具有的行为。但是请注意,底层实现可能具有不同的行为。虽然实体框架遵守这一点,但是像 LLBLGen 这样的 O/RM 在调用 First时也可以返回 null,这是一件非常奇怪的事情。这是一个非常奇怪(和顽固)的决定,由设计师 IMO。

以下是不同方法的概述:

  • Find ()-当您希望通过主键获取项时。如果找不到项,则返回 null。它将在访问数据库之前查看上下文(正如 Yaron 在评论中指出的那样) ,如果您需要在相同上下文存在的情况下多次获取相同实体,那么数据库是一个重要的效率因素。

  • Single ()-当您期望查询返回正好一个项时。如果查询没有正好返回一个项,这将引发异常。

  • SingleOrDefault ()-当您期望查询返回零个或一个项目时(即您不确定是否存在具有给定键的项目)。如果查询没有返回零个或一个项,这将引发异常。

  • First ()-当您希望查询返回一个或多个项目,但是只想访问代码中的第一个项目时(在此处的查询中,排序可能很重要)。如果查询没有返回至少一个项,这将引发异常。

  • FirstOrDefault ()-当您期望查询返回零个或多个条目,但是只想访问代码中的第一个条目时(即,您不确定是否存在具有给定键的条目)

这四个方法各有其位置,但实际上只有两个不同的操作。

  • 第一-期望包含多个项目的结果集,请给我该集合中的第一个项目。
  • 单一-期望一个单一的结果回来,给我的项目。

XxxxOrDefault ()版本只是添加了“我不想将空结果集视为异常情况”

我总是倾向于使用 FirstOrDefault。如果你真的想对性能挑剔,那么你应该在 EF 中使用 FirstOrDefault。在封面下,SingleOrDefault在查询中使用 top (2) ,因为它需要检查是否有第二行与条件匹配,如果匹配,则抛出异常。基本上,在 SingleOrDefault中,如果查询返回的记录超过1条,则表示希望引发异常。

Single () SingleOrDefault ()通常用于 ID 等唯一标识符,而 第一()FirstOrDefault ()通常用于可能有多个结果但只需要 “ Top 1”的查询。

如果没有返回结果,Single () 第一()将引发异常,SingleOrDefault ()FirstOrDefault ()捕获异常并返回 null 或 default (ResultDataType)。

另一方面,您可以按照核心逻辑划分这些方法,如下所示:

  • 方法将直接查询数据库 : < em > Single ()、 SingleOrDefault ()、 First ()、 FirstOrDefault ()
  • 方法将在对数据库 : < em > Find ()发出查询之前在缓存中执行搜索

对于一些性能细节,特别是在第二种情况下,您可以在这里查看: Https://msdn.microsoft.com/en-us/data/hh949853.aspx?f=255&mspperror=-2147217396#3

此外,在第一组中,您可以定义复杂的查询,但是使用 Find ()方法,您只能提供用于搜索的实体键。