zoukankan      html  css  js  c++  java
  • Entity Framework 4 in Action读书笔记——第四章:使用LINQ to Entities查询:分组数据

    4.3 分组数据

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

    解决方案:在查询中使用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 })
                 };

    投影的力量还可以允许分组数据包含关联实体的信息。在这里就不展示如何做了,因为它跟上一篇中的相似。

    LINQ to Entities甚至可以筛选分组后的数据。这就是接下来的主题。

    4.3.1筛选汇总数据

    筛选汇总数据等价于在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启用的最简单的任务。当涉及到关联时情况可能有些复杂,但现在你应该感到舒服。

  • 相关阅读:
    用 Sqlmap 识别 WAF
    OD 实验(九)
    跳转指令及其跳转条件
    Python
    Python 模块
    OD 实验(八)
    OD 实验(七)
    OD 实验(六)
    OD 实验(五)
    OD 实验(四)
  • 原文地址:https://www.cnblogs.com/nianming/p/2164129.html
Copyright © 2011-2022 走看看