linq iteration need for single row?
when i form the following code
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开发者_如何学C") == 0 select bt;
foreach (var v in s)
{
Console.WriteLine("{0}{1}",v.Vegetable.VegiName,v.Name);
}
my query returns single row only, then why do i need foreach iteration ? can't i use
Console.WriteLine("{0}{1}",s.Vegetable.VegiName,s.Name); directly ?
How is the compiler meant to know that your query will only return a single row? Suppose you changed your data to include another carrot - or no carrot at all - what would you expect to happen.
If you should definitely get a single result, call Single
to get it. If you may get multiple results, call First
. If you may get multiple results or none, call FirstOrDefault
. If you may get zero or one result, call SingleOrDefault
. For example, for the first case:
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);
Or alternatively:
var veg = rbt.Where(bt => bt.Vegetable.VegiName.CompareTo("carrot") == 0)
.Single();
Console.WriteLine("{0}{1}",veg.Vegetable.VegiName,veg.Name);
Because the type of the query IEnumerable<Rabbit>
, not Rabbit
. You can get what you want, though, by using a FirstOrDefault() or SingleOrDefault() at the end of your query.
var s = (from bt in rbt
where bt.Vegetable.VegiName.CompareTo("carrot") == 0
select bt)
.FirstOrDefault();
No, because LINQ does not know at compile time that s will return only a single row. Use the First() or Single() operator:
var v = (from bt in rbt where
bt.Vegetable.VegiName.CompareTo("carrot") == 0
select bt)
.First();
You can use the Single method to return a single value. Use SingleOrDefault if you suspect it may be null (ie. no results returned).
Rabbit result = s.SingleOrDefault();
if (result != null)
{
// use result
Console.WriteLine("{0} : {1}", result.Vegetable.VegiName, result.Name);
}
As others have mentioned, the alternative is to use First or FirstOrDefault to take the first result returned, if the query returns numerous results.
精彩评论