【发布时间】:2011-03-29 22:58:45
【问题描述】:
我正在寻找一个比较查询单个项目的不同方法以及何时使用每种方法的比较。
有没有人有一个链接来比较所有这些,或者快速解释一下为什么你会使用一个而不是另一个?还有更多我不知道的运算符吗?
谢谢。
【问题讨论】:
标签: .net linq entity-framework entity-framework-4 linq-to-entities
我正在寻找一个比较查询单个项目的不同方法以及何时使用每种方法的比较。
有没有人有一个链接来比较所有这些,或者快速解释一下为什么你会使用一个而不是另一个?还有更多我不知道的运算符吗?
谢谢。
【问题讨论】:
标签: .net linq entity-framework entity-framework-4 linq-to-entities
这真的很简单:Single 返回单个项目,如果没有或不止一个项目,则抛出异常。 First 将返回第一个项目或在没有项目时抛出。 FirstOrDefault 将返回第一项或在没有项时返回默认值(如果给定类型是引用类型,则为null)。
这是 API 应该具有的行为。但是请注意,底层实现可能具有不同的行为。虽然 Entity Framework 遵守这一点,但像 LLBLGen 这样的 O/RM 在调用 First 时也可以返回 null,这是一件非常奇怪的事情。这是设计师 IMO 做出的一个非常奇怪(而且很固执)的决定。
【讨论】:
Single 明确表示您只希望结果有一个元素。
以下是不同方法的概述:
Find() - 当您想通过主键获取项目时。如果找不到项目,这将返回 null。它会在进入数据库之前先查看上下文(正如 Yaron 在 cmets 中指出的那样),如果您需要在同一个上下文处于活动状态时多次获取同一个实体,这可能是一个重要的效率因素。
Single() - 当您期望查询只返回一个项目时。如果查询不只返回一个项目,这将引发异常。
SingleOrDefault() - 当您期望查询返回零个或一个项目时(即您不确定具有给定键的项目是否存在)。如果查询没有返回零个或一个项目,这将引发异常。
First() - 当您希望查询返回一个或多个项目但您只想访问代码中的第一项时(排序在此处的查询中可能很重要)。如果查询未返回至少一项,这将引发异常。
FirstOrDefault() - 当您希望查询返回零个或多个项目但您只想访问代码中的第一项时(即您不确定具有给定键的项目是否存在)
【讨论】:
Sales.OrderByDescending(s => s.TotalValue).First();
Single或SingleOrDefault会查询2条记录(限制2),而First或FirstOrDefault会查询1条(限制1)。
四种方法各有千秋;虽然你真的只有两种不同的操作。
xxxxOrDefault() 版本只是添加了“我不想将空结果集视为例外情况。”
【讨论】:
我总是倾向于使用FirstOrDefault。如果你真的想对性能很挑剔,那么你应该在 EF 中使用FirstOrDefault。在幕后SingleOrDefault 在查询中使用top (2),因为它需要检查是否有第二行与条件匹配,如果是,则抛出异常。基本上在SingleOrDefault 中,如果您的查询返回多于 1 条记录,您想抛出异常。
【讨论】:
FirstOrDefault 和SingleOrDefault 之间的性能差异显着?我会说在大多数情况下这是过早的优化。
Single()或SingleOrDefault()。我这样做的原因是通过编写错误的查询来发现错误,这些查询返回的次数超过了应有的结果,失败了。至少在我看来,这将有助于保持系统中的数据一致。当然这样比较慢,但我猜也不会慢多少,我愿意付出这个代价。
Single() 和 SingleOrDefault() 通常用于 ID 等唯一标识符,而 First() 或 FirstOrDefault () 通常用于可能有多个结果但您只需要 "Top 1" 的查询。
如果没有返回结果,Single() 或 First() 会抛出异常,SingleOrDefault() 和 FirstOrDefault( ) 捕获异常并返回 null 或 default(ResultDataType)。
【讨论】:
另一方面,你可以按照核心逻辑来划分这些方法,像这样:
有关一些性能细节,尤其是在第二种情况下,您可以查看此处: https://msdn.microsoft.com/en-us/data/hh949853.aspx?f=255&MSPPError=-2147217396#3
另外,在第一组中你可以定义复杂的查询,但是使用 Find() 方法你可以只提供实体键进行搜索。
【讨论】: