LINQ:
当我确定查询将返回一条记录时,使用Single()操作符比First()更有效吗?
有区别吗?
LINQ:
当我确定查询将返回一条记录时,使用Single()操作符比First()更有效吗?
有区别吗?
当前回答
单()
返回查询的单个特定元素 When Use:如果恰好需要1个元素;不是0或大于1。如果列表为空或包含多个元素,则会抛出异常"Sequence contains more than one element"
SingleOrDefault ()
返回查询的单个特定元素,如果没有找到结果,则返回默认值 当使用:当需要0或1个元素时。如果列表有2个或更多项,它将抛出异常。
第()
返回带有多个结果的查询的第一个元素。 When Use:当需要1个或多个元素,而您只需要第一个元素时。如果列表中不包含元素,它将抛出异常。
FirstOrDefault ()
Returns the first element of a list with any amount of elements, or a default value if the list is empty. When Use: When multiple elements are expected and you want only the first. Or the list is empty and you want a default value for the specified type, the same as default(MyObjectType). For example: if the list type is list<int> it will return the first number from the list or 0 if the list is empty. If it is list<string>, it will return the first string from the list or null if the list is empty.
其他回答
如果你期望一个单一的记录,在你的代码中显式总是好的。
我知道其他人已经写了为什么你要使用其中一个或另一个,但我认为我应该说明为什么你不应该使用一个,当你指的是另一个。
注意:在我的代码中,我通常会使用FirstOrDefault()和SingleOrDefault(),但这是一个不同的问题。
以一个表为例,它使用一个组合键(ID, Lang)存储不同语言的客户:
DBContext db = new DBContext();
Customer customer = db.Customers.Where( c=> c.ID == 5 ).First();
上面的代码引入了一个可能的逻辑错误(难以跟踪)。它将返回多个记录(假设您有多种语言的客户记录),但它总是只返回第一个记录……有时候可能有用……但其他人不是。它是不可预测的。
由于您的意图是返回一个单一客户使用Single();
下面的语句会抛出一个异常(这就是你在本例中想要的):
DBContext db = new DBContext();
Customer customer = db.Customers.Where( c=> c.ID == 5 ).Single();
然后,你就拍拍自己的额头,对自己说……哦!我忘了语言课了!以下是正确的版本:
DBContext db = new DBContext();
Customer customer = db.Customers.Where( c=> c.ID == 5 && c.Lang == "en" ).Single();
First()在以下场景中很有用:
DBContext db = new DBContext();
NewsItem newsitem = db.NewsItems.OrderByDescending( n => n.AddedDate ).First();
它将返回一个对象,由于您正在使用排序,它将返回最近的记录。
当您认为Single()应该显式地总是返回1条记录时,使用它将帮助您避免逻辑错误。
这两种方法在语义上有细微的差别。
使用Single从一个序列中检索第一个(也是唯一一个)元素,该序列应该只包含一个元素。如果序列中有多个元素,则调用Single将导致抛出异常,因为您指示了应该只有一个元素。
使用First从可以包含任意数量元素的序列中检索第一个元素。如果序列中有多个元素,则调用First不会引发异常,因为您表示只需要序列中的第一个元素,而不关心是否存在更多元素。
如果序列不包含元素,两个方法调用都会引发异常,因为两个方法都希望至少有一个元素存在。
我认识的很多人都使用FirstOrDefault(),但我更倾向于使用SingleOrDefault(),因为如果有多个,通常会出现某种数据不一致。不过,这是在处理LINQ-to-Objects。
他们是不同的。它们都断言结果集不是空的,但single也断言结果集不超过1个。我个人在只希望有1个结果的情况下使用Single,因为返回超过1个结果是一个错误,可能应该这样对待。
如果不特别希望在有多个项的事件中抛出异常,请使用First()。
两者都很有效率,就拿第一项来说。First()的效率稍微高一些,因为它不需要检查是否有第二个项。
唯一的区别是,Single()期望枚举中只有一个项开始,如果有多个项,则会抛出异常。如果您特别希望在这种情况下抛出异常,则使用. single()。