使用LINQ to Entities查询:分组数据

来源:互联网 发布:360云盘 mac 编辑:程序博客网 时间:2024/04/25 12:49

基本需求:根据送货城市分组返回所有订单。

解决方案:在查询中使用group ... by ...子句。

var result = from c in ctx.Orders             group c by c.ShippingAddress.City;


 

结果类型有点复杂,因为它是IEnumerable<IGrouping<string, Order>>的对象。IGrouping是一个特殊的类,它有一个键(Key)属性,在本例中是送货地址的值,和一个值(Value)属性。值属性是一个IEnumerable<T>集合,它包含对应Key的所有对象。例如,如果Key属性的值是Miami,Value属性包含所有送货地址是这个城市的订单。

遍历这个结果需要一个对所有Key的循环和一个内循环,内循环遍历对应Key的值。

foreach (var key in result)            {                Console.WriteLine(key.Key);                foreach (var item in key)                {                    Console.WriteLine(item.OrderId);                }            }


下面更改分组数据的名称。

var result = from c in ctx.Orders             group c by c.ShippingAddress.City into oGroup             select new { CityName = oGroup.Key, Items = oGroup };foreach (var key in result){    Console.WriteLine(key.CityName);    foreach (var item in key.Items)    {        Console.WriteLine(item.OrderId);    }}


前面已经提到分组键,但是我们没有解释分组键可以是什么。到目前为止,已经使用了单一的属性,但那只是可能性之一。通常,你要根据多个属性分组数据。例如,你可能想根据送货城市和邮政编码分组订单,以便更好的组织发货。在C#中,你必须使用匿名类型指定一个对象作为键,把送货城市和邮政编码放入其中。下面的代码使用了多个属性分组数据。

var result = from c in ctx.Orders             group c by new             {                 c.ShippingAddress.City,                 c.ShippingAddress.ZipCode             };foreach (var key in result){    Console.WriteLine(key.Key.City + "-" + key.Key.ZipCode);    foreach (var item in key)    {        Console.WriteLine(item.OrderId);    }}


正如可以自定义键值以反映你的需求,分组数据也可以使用投影以节省资源。你可以在分组的Select方法内的值列表中调用Select方法,如下:

var result = from c in ctx.Orders             group c by c.ShippingAddress.City into g             select new             {                 g.Key,                 Items = g.Select(og => new { og.OrderId, og.OrderDate })             };


 

var result = from c in ctx.Orders             group c by c.ShippingAddress.City into g             select new             {                 g.Key,                 Items = g.Select(og => new { og.OrderId, og.OrderDate })             };


筛选汇总数据

筛选汇总数据等价于在SQL中使用HAVING。举个例子,你可能想搜索按城市分组的订单,订单总数高于一个给定的数字。使用LINQ聚集家族的方法很容易就可以实现这一功能。

var result = from c in ctx.Orders             group c by c.ShippingAddress.City into g             where g.Count() > 2             select g;


 

分组后面的Where子句只影响分组后的数据。如果你需要在分组之前筛选,你必须在分组之前调用Where。根据Where子句放置的位置,查询中的变量可超出范围。我们修改一下上一段代码。如果你把Where放在group by子句之前,c变量在范围之内,但是g变量不在范围之内,因为还没有声明g。相反,如果把Where子句放在group by子句之后,c变量将不在范围之内,不能被引用,而g变量在范围之内,可以使用。

现在你已经掌握了筛选,投影和分组,下面将学习LINQ to Entities的另一个功能:sorting。它是由LINQ to Entities启用的最简单的任务。当涉及到关联时情况可能有些复杂,但现在你应该感到舒服。

 

0 0