当我形成以下代码时
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 ?
答案 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();