何时使用。第一次以及何时使用.FirstOrDefault和LINQ?

时间:2009-06-21 19:15:30

标签: c# .net linq

我一直在搜索并且没有真正找到关于何时使用.First以及何时希望将.FirstOrDefault与LINQ一起使用的明确答案。

  • 您希望何时使用.First?只有当你想要在没有返回结果时才能捕获异常?

    var result = List.Where(x => x == "foo").First();
    
  • 您希望何时使用.FirstOrDefault?如果没有结果,你总是想要默认类型吗?

    var result = List.Where(x => x == "foo").FirstOrDefault();
    
  • 就此而言,拿什么?

    var result = List.Where(x => x == "foo").Take(1);
    

14 个答案:

答案 0 :(得分:754)

当我知道或期望序列至少有一个元素时,我会使用First()。换句话说,当序列为空时出现异常情况。

当您知道需要检查是否有元素时,请使用FirstOrDefault()。换句话说,当序列为空时是合法的。您不应该依赖异常处理来进行检查。 (这是不好的做法,可能会损害表现)。

最后,First()Take(1)之间的区别在于First()返回元素本身,而Take(1)返回的元素序列恰好包含一个元素。

答案 1 :(得分:256)

.First会在没有结果时抛出异常。 .FirstOrDefault不会,它只返回null(引用类型)或值类型的默认值。 (例如对于int来说就像0。)这里的问题不是你想要的默认类型,而是更多:你是否愿意处理异常或处理默认值?由于例外应该是例外情况,因此当您不确定是否要从查询中获得结果时,首选FirstOrDefault。当逻辑上数据应该存在时,可以考虑异常处理。

在结果中设置分页时,通常会使用

Skip()Take()。 (如显示前10个结果,以及下一页的下10个结果等)

希望这会有所帮助。

答案 2 :(得分:103)

如果没有要返回的行,则first()将抛出异常,而.FirstOrDefault()将返回默认值(所有引用类型为NULL)。

因此,如果您已准备好并愿意处理可能的异常,.First()就可以了。如果你更愿意检查!= null的返回值,那么.FirstOrDefault()是你最好的选择。

但我想这也是个人偏好。使用对你更有意义的东西,更好地适应你的编码风格。

答案 3 :(得分:60)

第一个()

  1. 返回序列的第一个元素。
  2. 当结果中没有元素或源为null时抛出错误。
  3. 你应该使用它,如果预期有多个元素而你只想要第一个元素。
  4. FirstOrDefault()

    1. 返回序列的第一个元素,如果未找到任何元素,则返回默认值。
    2. 只有在源为空时才会抛出错误。
    3. 你应该使用它,如果预期有多个元素而你只想要第一个元素。 如果结果是空的也很好。
    4. 我们有一个UserInfos表,它有一些记录,如下所示。在下表的基础上,我创建了示例......

      UserInfo Table

      如何使用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:Sequence不包含元素

      如何使用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的记录。返回值为空

      希望它能帮助您了解何时使用First()FirstOrDefault()

答案 4 :(得分:18)

首先,Take是一种完全不同的方法。它会返回一个IEnumerable<T>而不是一个T,所以就这样了。

FirstFirstOrDefault之间,当您确定某个元素存在时,应该使用First,如果不存在,则会出现错误。

顺便说一下,如果您的序列包含default(T)元素(例如null)并且您需要区分为空且第一个元素为null,则不能使用{ {1}}。

答案 5 :(得分:13)

首先:

  • 返回序列的第一个元素
  • 引发异常:结果中没有元素
  • 使用时间:当预期超过1个元素且您只想要第一个

FirstOrDefault:

  • 返回序列的第一个元素,如果没有找到元素,则返回默认值
  • 抛出异常:仅当源为空时
  • 使用时间:当预期超过1个元素且您只想要第一个元素时。结果也可以是空的

来自:http://www.technicaloverload.com/linq-single-vs-singleordefault-vs-first-vs-firstordefault/

答案 6 :(得分:7)

另一个值得注意的区别是,如果您在生产环境中调试应用程序,则可能无法访问行号,因此识别方法中哪个特定.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));
}

答案 7 :(得分:4)

<强>首先()

当您知道结果包含多于1个元素时,您应该只是序列的第一个元素。

<强> FirstOrDefault()

FirstOrDefault()与First()类似,不同之处在于,如果没有元素匹配指定的条件,则返回基础类型的泛型集合的默认值。如果找不到元素,它不会抛出InvalidOperationException。但是元素或序列的集合是空的,而不是抛出异常。

答案 8 :(得分:3)

我找到一个网站,呼吁解释FirstOrDefault的需要 http://thepursuitofalife.com/the-linq-firstordefault-method-and-null-resultsets/
如果查询没有结果,并且您想调用First()或Single()来获取单行...您将获得“Sequence contains no elements”异常。

免责声明:我从未使用过LINQ,所以如果不这样做我会道歉。

答案 9 :(得分:2)

someList.First(); // exception if collection is empty.
someList.FirstOrDefault(); // first item or default(Type)

使用哪一个? 它应该由业务逻辑决定,而不是对异常/程序失败的恐惧。

例如, 如果业务逻辑说我们不能在任何工作日进行零交易(只是假设)。那么你不应该尝试通过一些智能编程来处理这种情况。 我总是会在这样的集合中使用First(),如果其他东西搞砸了业务逻辑,那就让程序失败。

代码:

var transactionsOnWorkingDay = GetTransactionOnLatestWorkingDay();
var justNeedOneToProcess = transactionsOnWorkingDay.First(): //Not FirstOrDefault()

我希望看到其他人对此发表评论。

答案 10 :(得分:2)

此类型的函数属于元素运算符。下面定义了一些有用的元素运算符。

  1. 首先/ FirstOrDefault
  2. 最后/ LastOrDefault
  3. 单/的SingleOrDefault
  4. 当我们需要根据特定条件从序列中选择单个元素时,我们使用元素运算符。这是一个例子。

      List<int> items = new List<int>() { 8, 5, 2, 4, 2, 6, 9, 2, 10 };
    

    First()运算符在满足条件后返回序列的第一个元素。如果没有找到任何元素,则会抛出异常。

    int result = items.Where(item =&gt; item == 2).First();

    FirstOrDefault()运算符在满足条件后返回序列的第一个元素。如果未找到任何元素,则它将返回该类型的默认值。

    int result1 = items.Where(item =&gt; item == 2).FirstOrDefault();

答案 11 :(得分:1)

好吧,让我给我两分钱。 First / Firstordefault适用于使用第二个构造函数的情况。我不会解释它是什么,但是当你可能总是使用它时,因为你不想引起异常。

person = tmp.FirstOrDefault(new Func<Person, bool>((p) =>
{
    return string.IsNullOrEmpty(p.Relationship);
}));

答案 12 :(得分:1)

其他人已经很好地描述了First()FirstOrDefault()之间的区别。我想进一步解释这些方法的语义。我认为FirstOrDefault被过度使用了。在大多数情况下,当您过滤数据时,您要么期望返回匹配逻辑条件的元素集合,要么期望通过其唯一标识符(例如,用户,书籍,帖子等)来获得单个唯一元素。为什么我们甚至可以说FirstOrDefault()是一种代码味道,不是因为它有问题,而是因为它使用得太频繁了。 This blog post详细探讨了该主题。在大多数情况下,IMO SingleOrDefault()都是更好的选择,因此请小心此错误,并确保您使用最能清楚地代表您的合同和期望的方法。

答案 13 :(得分:-8)

linq在集合上实现单个简单查询的方法很多,只需在sql中编写连接,根据需要和必要性,可以先应用或最后应用过滤器。

以下是我们可以在集合中找到具有id的元素的示例。 要在此处添加更多内容,当集合至少有一条记录时,方法First FirstOrDefault理想情况下会返回相同的值。但是,如果集合可以为空。然后First将返回例外,但FirstOrDefault将返回null或默认值。例如,int将返回0.因此,虽然这样做的使用是个人偏好,但最好使用FirstOrDefault来避免异常处理。 here is an example where, we run over a collection of transactionlist