.net LINQ:何时将 SingleOrDefault 与 FirstOrDefault() 与过滤条件一起使用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1745691/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
LINQ: When to use SingleOrDefault vs. FirstOrDefault() with filtering criteria
提问by p.campbell
Consider the IEnumerable extension methods SingleOrDefault()and FirstOrDefault()
考虑 IEnumerable 扩展方法SingleOrDefault()和FirstOrDefault()
MSDN documents that SingleOrDefault:
Returns the only element of a sequence, or a default value if the sequence is empty; this method throws an exception if there is more than one element in the sequence.
返回序列的唯一元素,如果序列为空,则返回默认值;如果序列中有多个元素,则此方法将引发异常。
whereas FirstOrDefaultfrom MSDN(presumably when using an OrderBy()or OrderByDescending()or none at all),
而FirstOrDefault来自 MSDN(大概在使用OrderBy()or OrderByDescending()或根本没有时),
Returns the first element of a sequence
返回序列的第一个元素
Consider a handful of example queries, it's not always clear when to use these two methods:
考虑一些示例查询,何时使用这两种方法并不总是很清楚:
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?
Question
题
What conventions do you follow or suggestwhen deciding to use SingleOrDefault()and FirstOrDefault()in your LINQ queries?
在决定在 LINQ 查询中使用SingleOrDefault()和时,您遵循或建议哪些约定FirstOrDefault()?
采纳答案by Bryan Menard
Whenever you use SingleOrDefault, you clearly state that the query should result in at most a singleresult. On the other hand, when FirstOrDefaultis used, the query can return any amount of results but you state that you only want the first one.
每当您使用 时SingleOrDefault,您都清楚地说明该查询最多只能产生一个结果。另一方面,当FirstOrDefault使用时,查询可以返回任意数量的结果,但您声明您只想要第一个。
I personally find the semantics very different and using the appropriate one, depending on the expected results, improves readability.
我个人发现语义非常不同,根据预期结果使用适当的语义可以提高可读性。
回答by Alex
If your result set returns 0 records:
如果您的结果集返回 0 条记录:
SingleOrDefaultreturns the default value for the type (e.g. default for int is 0)FirstOrDefaultreturns the default value for the type
SingleOrDefault返回类型的默认值(例如 int 的默认值为 0)FirstOrDefault返回类型的默认值
If you result set returns 1 record:
如果结果集返回 1 条记录:
SingleOrDefaultreturns that recordFirstOrDefaultreturns that record
SingleOrDefault返回那个记录FirstOrDefault返回那个记录
If your result set returns many records:
如果您的结果集返回许多记录:
SingleOrDefaultthrows an exceptionFirstOrDefaultreturns the first record
SingleOrDefault抛出异常FirstOrDefault返回第一条记录
Conclusion:
结论:
If you want an exception to be thrown if the result set contains many records, use SingleOrDefault.
如果您希望在结果集包含许多记录时抛出异常,请使用SingleOrDefault.
If you always want 1 record no matter what the result set contains, use FirstOrDefault
如果无论结果集包含什么,您总是想要 1 条记录,请使用 FirstOrDefault
回答by Stefan Steinegger
There is
有
- a semantical difference
- a performance difference
- 语义差异
- 性能差异
between the two.
两者之间。
Semantical Difference:
语义差异:
FirstOrDefaultreturns a first item of potentially multiple (or default if none exists).SingleOrDefaultassumes that there is a single item and returns it (or default if none exists). Multiple items are a violation of contract, an exception is thrown.
FirstOrDefault返回可能为多个的第一个项目(如果不存在则为默认值)。SingleOrDefault假设有一个项目并返回它(如果不存在则默认)。多项违反约定,抛出异常。
Performance Difference
性能差异
FirstOrDefaultis usually faster, it iterates until it finds the element and only has to iterate the whole enumerable when it doesn't find it. In many cases, there is a high probability to find an item.SingleOrDefaultneeds to check if there is only one element and therefore always iterates the whole enumerable. To be precise, it iterates until it finds a second element and throws an exception. But in most cases, there is no second element.
FirstOrDefault通常更快,它会迭代直到找到元素,并且只有在找不到元素时才需要迭代整个可枚举。在许多情况下,找到一个项目的概率很高。SingleOrDefault需要检查是否只有一个元素,因此总是迭代整个可枚举。准确地说,它会不断迭代,直到找到第二个元素并抛出异常。但在大多数情况下,没有第二个元素。
Conclusion
结论
Use
FirstOrDefaultif you don't care how many items there are orwhen you can't afford checking uniqueness (e.g. in a very large collection). When you check uniqueness on adding the items to the collection, it might be too expensive to check it again when searching for those items.Use
SingleOrDefaultif you don't have to care about performance too much and want to make sure that the assumption of a single item is clear to the reader and checked at runtime.
使用
FirstOrDefault,如果你不关心有多少项目有或当你不能检查的独特性(例如,在一个非常大的集合)。当您在将项目添加到集合时检查唯一性时,在搜索这些项目时再次检查它可能太昂贵了。使用
SingleOrDefault如果你没有在乎太多性能,并希望确保单个项目的前提是明确的读者,并在运行时检查。
In practice, you use First/ FirstOrDefaultoften even in cases when you assume a single item, to improve performance. You should still remember that Single/ SingleOrDefaultcan improve readability (because it states the assumption of a single item) and stability (because it checks it) and use it appropriately.
实际上,即使在假设单个项目的情况下,您也经常使用First/FirstOrDefault来提高性能。你仍然应该记住Single/SingleOrDefault可以提高可读性(因为它陈述了单个项目的假设)和稳定性(因为它检查了它)并适当地使用它。
回答by shalke
Nobody has mentioned that FirstOrDefault translated in SQL does TOP 1 record, and SingleOrDefault does TOP 2, because it needs to know is there more than 1 record.
没有人提到过 SQL 中翻译的 FirstOrDefault 做 TOP 1 记录,而 SingleOrDefault 做 TOP 2,因为它需要知道是否有超过 1 条记录。
回答by Prakash
For LINQ -> SQL:
对于 LINQ -> SQL:
SingleOrDefault
单一或默认
- will generate query like "select * from users where userid = 1"
- Select matching record, Throws exception if more than one records found
- Use if you are fetching data based on primary/unique key column
- 将生成类似“select * from users where userid = 1”的查询
- 选择匹配的记录,如果找到多条记录则抛出异常
- 如果您根据主/唯一键列获取数据,请使用
FirstOrDefault
首先或默认
- will generate query like "select top 1 * from users where userid = 1"
- Select first matching rows
- Use if you are fetching data based on non primary/unique key column
- 将生成类似“select top 1 * from users where userid = 1”这样的查询
- 选择第一个匹配的行
- 如果您根据非主键/唯一键列获取数据,请使用
回答by spender
I use SingleOrDefaultin situations where my logic dictates that the will be either zero or one results. If there are more, it's an error situation, which is helpful.
我SingleOrDefault在我的逻辑规定结果为零或一的情况下使用。如果有更多,则是错误情况,这很有帮助。
回答by Steven
SingleOrDefault: You're saying that "At most" there is one item matching the query or default FirstOrDefault: You're saying that there is "At least" one item matching the query or default
SingleOrDefault:您是说“最多”有一项与查询或默认值匹配 FirstOrDefault:您是说“至少”有一项与查询或默认值匹配
Say that out loud next time you need to choose and you shall likely choose wisely. :)
下次您需要选择时大声说出来,您可能会明智地选择。:)
回答by Olli
In your cases, I would use the following:
在您的情况下,我将使用以下内容:
select by ID==5: it's OK to use SingleOrDefault here, because you expect one [or none] entity, if you got more than one entity with ID 5, there's something wrong and definitely exception worthy.
select by ID==5: 在这里使用 SingleOrDefault 是可以的,因为您期望有一个 [或没有] 实体,如果您有多个 ID 为 5 的实体,则说明有问题并且绝对值得例外。
when searching for people whose first name equals "Bobby", there can be more than one (quite possibly I would think), so you should neither use Single nor First, just select with the Where-operation (if "Bobby" returns too many entities, the user has to refine his search or pick one of the returned results)
在搜索名字等于“Bobby”的人时,可能有多个(我很可能会这么想),所以你不应该使用 Single 或 First,只需使用 Where 操作进行选择(如果“Bobby”返回太多实体,用户必须优化他的搜索或选择返回的结果之一)
the order by creation date should also be performed with a Where-operation (unlikely to have only one entity, sorting wouldn't be of much use ;) this however implies you want ALL entities sorted - if you want just ONE, use FirstOrDefault, Single would throw every time if you got more than one entity.
按创建日期排序也应该使用 Where 操作(不太可能只有一个实体,排序没有多大用处;)但这意味着您希望对所有实体进行排序 - 如果您只想要一个,请使用 FirstOrDefault,如果你有多个实体,Single 每次都会抛出。
回答by Sheo Dayal Singh
Both are the element operators and they are used to select a single element from a sequence. But there is a minor difference between them. SingleOrDefault() operator would throw an exception if more than one elements are satisfied the condition where as FirstOrDefault() will not throw any exception for the same. Here is the example.
两者都是元素运算符,它们用于从序列中选择单个元素。但它们之间有细微的差别。如果满足多个元素,则 SingleOrDefault() 运算符将引发异常,而 FirstOrDefault() 不会为此引发任何异常。这是示例。
List<int> items = new List<int>() {9,10,9};
//Returns the first element of a sequence after satisfied the condition more than one elements
int result1 = items.Where(item => item == 9).FirstOrDefault();
//Throw the exception after satisfied the condition more than one elements
int result3 = items.Where(item => item == 9).SingleOrDefault();
回答by bytebender
In your last example:
在你的最后一个例子中:
var latestCust = db.Customers
.OrderByDescending(x=> x.CreatedOn)
.FirstOrDefault();//Single or First, or doesn't matter?
Yes it does. If you try to use SingleOrDefault()and the query results in more than record you would get and exception. The only time you can safely use SingleOrDefault()is when you are expecting only 1 and only 1 result...
是的,它确实。如果您尝试使用SingleOrDefault()并且查询结果超过记录,您会得到和异常。您唯一可以安全使用的时间SingleOrDefault()是当您只期待 1 个且只有 1 个结果时......

