在LINQ中混合Any()和First()?

时间:2012-01-10 09:12:20

标签: c# linq

首先是LINQ中的菜鸟! 然后,问题是我有一个收集:

  1. 要么不包含我的ID(字符串)
  2. 或仅包含一次
  3. 我想使用Where但我不喜欢我必须执行的if指令...所以这是我的代码:

    if (MyCollection.Any(rm => rm.BaseName == rbName))
    {
        var tmp = MyCollection.First(rm => rm.BaseName == rbName);
    }
    

    这有效,但我觉得这不是我应该用LINQ做的方式... 有什么建议吗?

7 个答案:

答案 0 :(得分:16)

非唯一实体回答(除了抛出多个实例)

使用SingleOrDefault。这将返回唯一项(如果存在),如果不存在则返回null,如果存在多个项,则返回异常。

var tmp = MyCollection.SingleOrDefault(rm => rm.BaseName == rbName);

独特财产回答(永远不会有多个实例)

如果您的系统已设置为BaseName是一个唯一的实体,用户FirstOrDefault,如果有多个因为它将在第一个实例停止,则不会抛出异常,但是系统将被设计为永远不会有相同的实例,因此可以接受(并减少时间)。

var tmp = MyCollection.FirstOrDefault(rm => rm.BaseName == rbName);

答案 1 :(得分:12)

正如ThePower所说,你应该使用SingleOrDefaultFirstOrDefault。如果真的只有一个这样的条目,他们会做同样的事情,但如果你使用LINQ to Objects FirstOrDefault可能会更快 - SingleOrDefault必须扫描整个序列来检查没有任何其他比赛。

如果有多个匹配项,SingleOrDefault将抛出异常; FirstOrDefault将返回第一场比赛。

所以你可以使用:

var result = MyCollection.FirstOrDefault(rm => rm.BaseName == rbName);
if (result != null)
{
    // Use it
}

请注意,如果您的序列元素类型是值类型,这可能会很麻烦,因为您可能无法区分由于没有匹配而导致的元素类型的默认值,以及“实际”值。看起来在这种情况下不太可能出现问题,但值得记住。

答案 2 :(得分:5)

var tmp = MyCollection.FirstOrDefault(rm => rm.BaseName == rbName));

如果你没有这样的记录,tmp将为null。

答案 3 :(得分:2)

你可以使用,

FirstOrDefault()

SingleOrDefault()

答案 4 :(得分:1)

使用FirstOrDefault(rm => rm.BaseName == rbName);

msdn link

答案 5 :(得分:1)

Any返回bool以指示此类项是否存在,First会从您的集合中返回记录。因此,无论如何,您将拥有来自集合的对象和您的条件结果。您可以使用FirstOrDefault,然后检查null您的返回值。

var tmp = MyCollection.FirstOrDefault(rm => rm.BaseName == rbName);
if (tmp != null) 
{
    // do something
}

答案 6 :(得分:1)

var tmp = MyCollection.FirstOrDefault(rm => rm.BaseName == rbName);
if (tmp != null)
{
    // Do something
}