我四处搜索,并没有真正找到关于何时使用 .First
以及何时将 .FirstOrDefault
与 LINQ 一起使用的明确答案。
您想什么时候使用 .First?仅当您想在没有返回结果的情况下捕获异常时? var 结果 = List.Where(x => x == "foo").First();
你什么时候想使用.FirstOrDefault?如果没有结果,您何时总是想要默认类型? var 结果 = List.Where(x => x == "foo").FirstOrDefault();
就此而言,Take 怎么样? var 结果 = List.Where(x => x == "foo").Take(1);
.First
和 .FirstOrDefault
都将谓词作为参数,因此 var result = List.Where(x => x == "foo").First();
可以重写为 var result = List.First(x => x == "foo");
Single
和 SingleOrDefault
。我讨厌人们在真正的意思是 Single
时使用 First
; )
.FirstOrDefault()
总是让您有机会抛出更有意义的异常。如果引发了序列异常并且方法中有多个 .First()
,则可能难以辨别哪个语句是问题所在。
当我知道或期望序列至少有一个元素时,我会使用 First()
。换句话说,当序列为空是异常情况时。
当您知道需要检查是否存在元素时,请使用 FirstOrDefault()
。换句话说,什么时候序列为空是合法的。您不应该依赖异常处理来进行检查。 (这是不好的做法,可能会损害性能)。
最后,First()
和 Take(1)
之间的区别在于 First()
返回元素本身,而 Take(1)
返回仅包含一个元素的元素序列。
.First
将在没有结果时引发异常。 .FirstOrDefault
不会,它只会返回 null(引用类型)或值类型的默认值。 (例如,对于 int 而言,如 0
。)这里的问题不是您何时需要默认类型,而是更多:您愿意处理异常还是处理默认值?由于异常应该是异常的,因此当您不确定是否要从查询中获得结果时,首选 FirstOrDefault
。当逻辑上数据应该在那里时,可以考虑异常处理。
Skip()
和 Take()
通常用于在结果中设置分页。 (比如在下一页显示前 10 个结果,接下来的 10 个等)
希望这可以帮助。
如果没有要返回的行,.First()
将引发异常,而 .FirstOrDefault()
将返回默认值(所有引用类型的 NULL
)。
因此,如果您准备好并愿意处理可能出现的异常,.First()
就可以了。如果您更愿意检查 != null
的返回值,那么 .FirstOrDefault()
是您更好的选择。
但我想这也有点个人喜好。使用对您更有意义且更适合您的编码风格的那个。
第一的()
返回序列的第一个元素。当结果中没有元素或源为空时,它会引发错误。你应该使用它,如果需要多个元素并且你只想要第一个元素。
第一或默认()
返回序列的第一个元素,如果没有找到元素,则返回默认值。仅当源为空时才会引发错误。你应该使用它,如果需要多个元素并且你只想要第一个元素。如果结果为空也很好。
我们有一个 UserInfos 表,其中有一些记录,如下所示。根据下表,我创建了示例...
https://i.stack.imgur.com/fJntd.png
如何使用 First()
var result = dc.UserInfos.First(x => x.ID == 1);
只有一条记录 ID== 1。应返回此记录 ID:1 名字:Manish 姓氏:Dubey 电子邮件:xyz@xyz.com
var result = dc.UserInfos.First(x => x.FName == "Rahul");
有多个记录,其中 FName == "Rahul"。第一条记录应该返回。 ID:7 名字:Rahul 姓氏:Sharma 电子邮件:xyz1@xyz.com
var result = dc.UserInfos.First(x => x.ID ==13);
没有 ID== 13 的记录。应该会发生错误。 InvalidOperationException:序列不包含任何元素
如何使用 FirstOrDefault()
var result = dc.UserInfos.FirstOrDefault(x => x.ID == 1);
只有一条记录 ID== 1。应返回此记录 ID:1 名字:Manish 姓氏:Dubey 电子邮件:xyz@xyz.com
var result = dc.UserInfos.FirstOrDefault(x => x.FName == "Rahul");
有多个记录,其中 FName == "Rahul"。第一条记录应该返回。 ID:7 名字:Rahul 姓氏:Sharma 电子邮件:xyz1@xyz.com
var result = dc.UserInfos.FirstOrDefault(x => x.ID ==13);
没有ID== 13的记录。返回值为null
希望它能帮助您了解何时使用 First()
或 FirstOrDefault()
。
首先,Take
是一种完全不同的方法。它返回一个 IEnumerable<T>
而不是一个 T
,所以就这样了。
在 First
和 FirstOrDefault
之间,您应该在确定元素存在时使用 First
,如果不存在,则说明存在错误。
顺便说一句,如果您的序列包含 default(T)
元素(例如 null
)并且您需要区分为空和第一个元素是 null
,则不能使用 FirstOrDefault
。
第一的:
返回序列的第一个元素
抛出异常:结果中没有元素
在以下情况下使用:当预期有多个元素并且您只想要第一个元素时
第一个或默认值:
返回序列的第一个元素,如果没有找到元素,则返回默认值
抛出异常:仅当源为空时
在以下情况下使用:当预期有多个元素并且您只需要第一个元素时。结果也可以为空
来自:http://www.technicaloverload.com/linq-single-vs-singleordefault-vs-first-vs-firstordefault/
另一个需要注意的区别是,如果您在生产环境中调试应用程序,您可能无法访问行号,因此确定方法中哪个特定 .First()
语句引发了异常可能很困难。
异常消息也不会包含您可能使用过的任何 Lambda 表达式,这会使任何问题更难调试。
这就是为什么我总是使用 FirstOrDefault()
,即使我知道空条目会构成异常情况。
var customer = context.Customers.FirstOrDefault(i => i.Id == customerId);
if (customer == null)
{
throw new Exception(string.Format("Can't find customer {0}.", customerId));
}
ArgumentException
)或定义自定义异常类型(例如 RecordNotFoundException
)。
第一的()
当您知道结果包含超过 1 个预期的元素并且您应该只使用序列的第一个元素时。
第一或默认()
FirstOrDefault() 与 First() 类似,不同之处在于,如果没有元素匹配指定条件,则返回泛型集合的基础类型的默认值。如果没有找到元素,它不会抛出 InvalidOperationException。但是元素或序列的集合是空的,而不是引发异常。
这种类型的函数属于元素运算符。下面定义了一些有用的元素运算符。
First/FirstOrDefault Last/LastOrDefault Single/SingleOrDefault
当我们需要根据特定条件从序列中选择单个元素时,我们会使用元素运算符。这是一个例子。
List<int> items = new List<int>() { 8, 5, 2, 4, 2, 6, 9, 2, 10 };
First() 运算符在满足条件后返回序列的第一个元素。如果没有找到元素,那么它将抛出异常。
int result = items.Where(item => item == 2).First();
FirstOrDefault() 运算符在满足条件后返回序列的第一个元素。如果没有找到元素,那么它将返回该类型的默认值。
int result1 = items.Where(item => item == 2).FirstOrDefault();
我发现一个网站可以解释 FirstOrDefault
http://thepursuitofalife.com/the-linq-firstordefault-method-and-null-resultsets/
如果查询没有结果,并且您想调用 First() 或 Single() 来获得单行.. . 你会得到一个“序列不包含元素”的异常。
免责声明:我从未使用过 LINQ,所以如果这离题了,我深表歉意。
其他人已经很好地描述了 First()
和 FirstOrDefault()
之间的区别。我想进一步解释这些方法的语义。在我看来,FirstOrDefault
被过度使用了。在大多数情况下,当您过滤数据时,您要么期望返回与逻辑条件匹配的元素集合,要么通过其唯一标识符获取单个唯一元素——例如用户、书籍、帖子等......为什么我们甚至可以说 FirstOrDefault()
是一种代码味道,不是因为它有问题,而是因为它被使用得太频繁了。 This blog post 详细探讨了该主题。在大多数情况下,IMO SingleOrDefault()
是一个更好的选择,因此请注意这个错误,并确保您使用最合适的方法,清楚地代表您的合同和期望。
.SingleOrDefault()
可能很容易被滥用,并且可能会影响某些类型的查询的性能。 .SingleOrDefault()
的底层实现实际上使用 .Take(2)
然后应用验证逻辑。代码气味更多地在于我们为什么使用 OrDefault(),而不一定是 First vs Single 如果我们的代码已经预先假设或预先验证条件只会返回 1 行或不返回任何行,我们是否需要在方法链的后面继续使用和验证 .Single()
?
someList.First(); // exception if collection is empty.
someList.FirstOrDefault(); // first item or default(Type)
使用哪一个?它应该由业务逻辑决定,而不是担心异常/程序失败。
例如,如果业务逻辑说我们在任何工作日都不能有零交易(假设)。那么你不应该尝试用一些聪明的编程来处理这种情况。我将始终在此类集合上使用 First(),如果其他事情搞砸了业务逻辑,则让程序失败。
代码:
var transactionsOnWorkingDay = GetTransactionOnLatestWorkingDay();
var justNeedOneToProcess = transactionsOnWorkingDay.First(): //Not FirstOrDefault()
我想看看其他人对此的评论。
好吧,让我给我两分钱。 First / Firstordefault 用于使用第二个构造函数时。我不会解释它是什么,但它是你可能总是使用一个,因为你不想引起异常。
person = tmp.FirstOrDefault(new Func<Person, bool>((p) =>
{
return string.IsNullOrEmpty(p.Relationship);
}));
linq 有很多方法可以实现对集合的单个简单查询,只需我们在 sql 中编写连接,可以根据需要和必要性首先或最后应用过滤器。
https://i.stack.imgur.com/a7jGs.png
Take
的工作原理,然后再解释一下First()
与Take(1)
的相同之处