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

asf*_*adf 111 .net linq linq-to-entities entity-framework entity-framework-4

我有一个时间的魔鬼找到一个比较查询单个项目的不同方法,以及何时使用每个项目.

有没有人有一个比较所有这些的链接,或快速解释为什么你会使用一个而不是另一个?还有更多我不了解的运营商吗?

谢谢.

Ste*_*ock 198

以下是不同方法的概述:

  • 查找() - 当您想通过主键获取项目时.如果找不到项目,则返回null.它将在进入数据库之前查看上下文(正如Yaron在评论中所指出的那样),如果你需要在相同的上下文存活时多次获得相同的实体,这可能是一个重要的效率因素.

  • Single() - 当您希望查询返回一个项目时.如果查询不返回一个项,则会抛出异常.

  • SingleOrDefault() - 当您希望查询返回零个或一个项目时(即您不确定是否存在具有给定键的项目).如果查询未返回零个或一个项,则会抛出异常.

  • First() - 当您希望查询返回一个或多个项目但您只想访问代码中的第一个项目时(在此查询中排序可能很重要).如果查询不返回至少一个项,则会抛出异常.

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

  • 所有评论都看起来很重要.Find()是在命中db之前搜索上下文的唯一方法. (5认同)
  • 另一点是在查询sql数据库时,`Single`或`SingleOrDefault`将查询2条记录(限制2),而`First`或`FirstOrDefault`将查询1(限制1). (5认同)
  • 啊,谢谢.另一个似乎完成了同样的事情 - 哈哈. (2认同)
  • 当您只想检索排序依据中最高或最低的对象时,First() 最有意义。例如,为我找到总价值最高的销售。`Sales.OrderByDescending(s => s.TotalValue).First();` (2认同)

小智 19

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

  • 您是否曾测量过`FirstOrDefault`和`SingleOrDefault`之间的性能差异?我认为在大多数情况下这是过早的优化. (5认同)
  • 当我返回*应该*只存在*一个*的东西时,我倾向于使用 `Single()` 或 `SingleOrDefault()`。我这样做的原因是通过编写错误的查询来发现错误,这些查询会返回超过应有的结果,从而失败。至少在我看来,这将有助于保持系统中的数据一致。当然这会慢一些,但我猜也不会慢多少,而且我愿意付出这个代价。 (2认同)

Ste*_*ven 15

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

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

  • 如果你喜欢你的代码"快速失败",First()和Single()让你的代码更精确地说出预期的内容(否则它会失败) (7认同)
  • 我完全赞同弗兰克.这也是关于沟通意图.`Single`清楚地表明你只希望结果有一个元素. (3认同)

Chr*_*fer 8

这四种方法各有所长; 虽然你真的只有两种不同的操作.

  • 首先 - 期望包含多个项目的结果集,给我该集合中的第一个项目.
  • 单 - 期待一个结果,给我那个项目.

xxxxOrDefault()版本只是添加了"我不想将空结果集视为异常情况".

  • 不幸的是,许多开发人员纯粹使用First()或FirstOrDefault()作为防御措施,认为它可以避免异常,因为它真的有可能隐藏真正的问题. (3认同)