p.c*_*ell 487 .net linq linq-to-sql
考虑IEnumerable扩展方法SingleOrDefault()
和FirstOrDefault()
返回序列的唯一元素,如果序列为空,则返回默认值; 如果序列中有多个元素,则此方法抛出异常.
而FirstOrDefault
从MSDN(推测当使用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?
Run Code Online (Sandbox Code Playgroud)
题
你遵循或暗示什么约定决定要使用时SingleOrDefault()
,并FirstOrDefault()
在您的LINQ查询?
Ale*_*lex 563
如果结果集返回0条记录:
SingleOrDefault
返回类型的默认值(例如,int的默认值为0)FirstOrDefault
返回该类型的默认值如果结果集返回1条记录:
SingleOrDefault
返回该记录FirstOrDefault
返回该记录如果结果集返回许多记录:
SingleOrDefault
抛出一个例外FirstOrDefault
返回第一条记录结论:
如果要在结果集包含许多记录时抛出异常,请使用SingleOrDefault
.
如果您总是想要1条记录,无论结果集包含什么,请使用 FirstOrDefault
Bry*_*ard 448
无论何时使用SingleOrDefault
,您都清楚地声明查询最多只能产生一个结果.另一方面,当FirstOrDefault
使用时,查询可以返回任何数量的结果,但是您声明只需要第一个结果.
我个人发现语义非常不同,使用适当的语义,取决于预期的结果,提高了可读性.
Ste*_*ger 235
有
两者之间.
语义差异:
FirstOrDefault
返回可能多次的第一项(如果不存在,则返回默认值).SingleOrDefault
假设有一个项目并返回它(如果不存在则默认).多个项目违反合同,抛出异常.性能差异
FirstOrDefault
通常更快,它迭代直到找到元素,并且只有在它找不到时才需要迭代整个枚举.在许多情况下,很有可能找到一个项目.
SingleOrDefault
需要检查是否只有一个元素,因此总是迭代整个可枚举元素.确切地说,它会迭代,直到找到第二个元素并抛出异常.但在大多数情况下,没有第二个因素.
结论
使用FirstOrDefault
,如果你不关心有多少项目有或当你不能检查的独特性(例如,在一个非常大的集合).当您检查将项目添加到集合时的唯一性时,在搜索这些项目时再次检查它可能太昂贵了.
使用SingleOrDefault
如果你没有在乎太多性能,并希望确保单个项目的前提是明确的读者,并在运行时检查.
在实践中,即使在假设单个项目的情况下,也经常使用First
/ FirstOrDefault
来提高性能.您仍然应该记住Single
/ SingleOrDefault
可以提高可读性(因为它表示单个项目的假设)和稳定性(因为它检查它)并适当地使用它.
sha*_*lke 71
没有人提到在SQL中翻译的FirstOrDefault执行TOP 1记录,而SingleOrDefault执行TOP 2,因为它需要知道是否有超过1条记录.
Pra*_*ash 17
对于LINQ - > SQL:
的SingleOrDefault
FirstOrDefault
spe*_*der 10
我SingleOrDefault
在我的逻辑规定将为零或一个结果的情况下使用.如果有更多,这是一个错误的情况,这是有帮助的.
在你的情况下,我会使用以下内容:
select by ID==5:这里使用 SingleOrDefault 是可以的,因为您期望一个[或没有]实体,如果您有多个 ID 为 5 的实体,则存在错误并且绝对值得例外。
当搜索名字等于“Bobby”的人时,可能会有多个(我认为很可能),所以你不应该使用 Single 或 First,只需使用Where操作进行选择(如果“Bobby”返回太多实体,用户必须优化其搜索或选择返回的结果之一)
按创建日期排序还应该使用Where操作执行(不太可能只有一个实体,排序没有多大用处;)但这意味着您希望对所有实体进行排序 - 如果您只想要一个实体,请使用FirstOrDefault,如果你有多个实体,每次都会抛出 Single。
小智 5
SingleOrDefault:您说"最多"有一个项目与查询匹配或默认FirstOrDefault:您说的是"至少"有一个项目与查询匹配或默认
下次你需要选择大声说出来,你可能会明智地选择.:)