linq迭代需要单行吗?

时间:2009-10-18 21:58:48

标签: linq

当我形成以下代码时

Rabbit[] rbt=
new Rabbit[]
{
   new Rabbit{ Name="Jobby", Vegetable=new Vegetable{ VegiName="carrot"}},
   new Rabbit{ Name="hobby", Vegetable=new Vegetable{ VegiName="Beetroot"}}
};

var s = from bt in rbt where
        bt.Vegetable.VegiName.CompareTo("carrot") == 0 select bt;

foreach (var v in s)
{
                Console.WriteLine("{0}{1}",v.Vegetable.VegiName,v.Name);
}

我的查询只返回单行,那为什么我需要foreach迭代?我不能用

Console.WriteLine("{0}{1}",s.Vegetable.VegiName,s.Name); directly ?

4 个答案:

答案 0 :(得分:8)

编译器如何知道您的查询只返回一行? 假设您更改了数据以包含另一个胡萝卜 - 或根本没有胡萝卜 - 您期望发生什么。

如果你肯定会得到一个结果,请致电Single获取它。如果您可能获得多个结果,请致电First。如果您可能获得多个结果或没有结果,请致电FirstOrDefault。如果您可能得到零或一个结果,请致电SingleOrDefault。例如,对于第一种情况:

var s = from bt in rbt where
        bt.Vegetable.VegiName.CompareTo("carrot") == 0 select bt;

var veg = s.Single();

Console.WriteLine("{0}{1}",veg.Vegetable.VegiName,veg.Name);

或者:

var veg = rbt.Where(bt => bt.Vegetable.VegiName.CompareTo("carrot") == 0)
             .Single();
Console.WriteLine("{0}{1}",veg.Vegetable.VegiName,veg.Name);

答案 1 :(得分:2)

因为查询的类型为IEnumerable<Rabbit>,而不是Rabbit。但是,您可以通过在查询结尾处使用FirstOrDefault()或SingleOrDefault()来获得所需内容。

var s = (from bt in rbt
         where bt.Vegetable.VegiName.CompareTo("carrot") == 0
         select bt)
        .FirstOrDefault();

答案 2 :(得分:1)

您可以使用Single method返回单个值。如果您怀疑它可能为空(即没有返回结果),请使用SingleOrDefault

Rabbit result = s.SingleOrDefault();

if (result != null)
{
    // use result
    Console.WriteLine("{0} : {1}", result.Vegetable.VegiName, result.Name);
}

正如其他人所提到的,另一种方法是使用First或FirstOrDefault来获取返回的第一个结果,如果查询返回了大量结果。

答案 3 :(得分:1)

不,因为LINQ在编译时不知道s只返回一行。使用First()或Single()运算符:

var v = (from bt in rbt where
         bt.Vegetable.VegiName.CompareTo("carrot") == 0 
         select bt)
        .First();