Arm*_*est 300
我知道其他人已经写过为什么你使用其中一个,但我想我会说明为什么你不应该使用一个,当你的意思是另一个.
注意:在我的代码中,我通常会使用FirstOrDefault()
,SingleOrDefault()
但这是一个不同的问题.
例如,Customers
使用复合键(ID
,Lang
)以不同语言存储的表:
DBContext db = new DBContext();
Customer customer = db.Customers.Where( c=> c.ID == 5 ).First();
Run Code Online (Sandbox Code Playgroud)
上面的代码引入了可能的逻辑错误(难以跟踪).它将返回多个记录(假设您有多种语言的客户记录),但它总是只返回第一个...有时可能有效......但不能返回其他语言.这是不可预测的.
因为你的意图是返回单一Customer
用途Single()
;
以下将抛出一个异常(在这种情况下你想要的):
DBContext db = new DBContext();
Customer customer = db.Customers.Where( c=> c.ID == 5 ).Single();
Run Code Online (Sandbox Code Playgroud)
然后,你只需按下额头,然后对自己说......哎呀!我忘记了语言领域!以下是正确的版本:
DBContext db = new DBContext();
Customer customer = db.Customers.Where( c=> c.ID == 5 && c.Lang == "en" ).Single();
Run Code Online (Sandbox Code Playgroud)
First()
在以下场景中很有用:
DBContext db = new DBContext();
NewsItem newsitem = db.NewsItems.OrderByDescending( n => n.AddedDate ).First();
Run Code Online (Sandbox Code Playgroud)
它将返回一个对象,并且由于您正在使用排序,它将是返回的最新记录.
使用Single()
时感觉它应该明确,始终返回1条记录将有助于你避免逻辑错误.
Alw*_*mer 67
如果找到符合条件的多条记录,则Single将抛出异常.首先将始终从列表中选择第一条记录.如果查询只返回1条记录,则可以使用First()
.
InvalidOperationException
如果集合为空,则两者都将抛出异常.或者你可以使用SingleOrDefault()
.如果列表为空,则不会抛出异常
Die*_*des 28
单()
返回查询的单个特定元素
使用时:如果恰好有1个元素; 不是0或大于1.如果列表为空或具有多个元素,它将抛出异常"序列包含多个元素"
的SingleOrDefault()
返回查询的单个特定元素,如果未找到结果,则返回默认值
使用时:预期为0或1个元素时.如果列表包含2个或更多项,它将抛出异常.
第一()
返回具有多个结果的查询的第一个元素.
使用时:当需要一个或多个元素时,您只需要第一个元素.如果列表不包含任何元素,它将抛出异常.
FirstOrDefault()
返回包含任意数量元素的列表的第一个元素,如果列表为空,则返回默认值.
使用时:当预期有多个元素且您只想要第一个元素时.或者列表为空,您需要指定类型的默认值,与之相同
default(MyObjectType)
.例如:如果列表类型是list<int>
,它将返回列表中的第一个数字,如果列表为空,则返回0.如果是list<string>
,它将从列表返回第一个字符串,如果列表为空则返回null.
And*_*are 18
这两种方法之间存在细微的语义差异.
用于Single
从应该包含一个元素但不再包含一个元素的序列中检索第一个(也是唯一的)元素.如果序列具有多于on元素,Single
则调用将导致抛出异常,因为您指示应该只有一个元素.
用于First
从可包含任意数量元素的序列中检索第一个元素.如果序列具有多于on元素,First
则调用不会导致抛出异常,因为您指示只需要序列中的第一个元素而不关心是否存在更多元素.
如果序列不包含任何元素,则两个方法调用都将导致抛出异常,因为两个方法都期望至少存在一个元素.
Pat*_*her 16
如果您不希望在有多个项目的情况下抛出异常,请使用First()
.
两者都很有效率,拿第一项. First()
效率稍高,因为它不会检查是否有第二项.
唯一的区别是Single()
期望枚举中只有一个项目开始,并且如果有多个项目将抛出异常.您使用 .Single()
,如果你特别想要抛出的异常在这种情况下.
Eti*_*tel 14
如果我记得,Single()检查第一个元素后面是否有另一个元素(如果是这种情况则抛出异常),而First()在获取后停止.如果序列为空,则两者都抛出异常.
个人而言,我总是使用First().
小智 8
关于性能:一位同事和我正在讨论Single vs First(或SingleOrDefault vs FirstOrDefault)的性能,我正在争论First(或FirstOrDefault)会更快并提高性能(我只是为了制作我们的应用程序)跑得更快).
我已经阅读了有关Stack Overflow的几篇文章.有人说使用First而不是Single会有很小的性能提升.这是因为First只返回第一项,而Single必须扫描所有结果以确保没有重复(即:如果它在表的第一行中找到该项,它仍然会扫描每隔一行确保没有第二个值匹配条件然后会抛出错误).我觉得自己处于坚实的基础上,"第一"比"单身"更快,所以我开始证明这一点并让辩论得以休息.
我在我的数据库中设置了一个测试并添加了1,000,000行ID UniqueIdentifier外部UniqueIdentifier信息nvarchar(50)(填充了数字"0"到"999,9999"的字符串
我加载了数据并将ID设置为主键字段.
使用LinqPad,我的目标是表明如果你使用Single搜索'Foreign'或'Info'的值,那将比使用First更糟糕.
我无法解释我得到的结果.几乎在所有情况下,使用Single或SingleOrDefault稍微快一些.这对我来说没有任何合理意义,但我想分享一下.
例如:我使用了以下查询:
var q = TestTables.First(x=>x.Info == "314638") ;
//Vs.
Var q = TestTables.Single(x=>x.Info =="314638") ; //(this was slightly faster to my surprise)
Run Code Online (Sandbox Code Playgroud)
我在'外部'关键字段上尝试了类似的查询,这个字段没有被编入索引,认为First会更快,但Single在我的测试中总是稍微快一些.
您可以尝试简单的示例以获取差异。第三行将引发异常;
List<int> records = new List<int>{1,1,3,4,5,6};
var record = records.First(x => x == 1);
record = records.Single(x => x == 1);
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
86536 次 |
最近记录: |