【问题标题】:Generate a report from Northwind DB using Linq使用 Linq 从 Northwind DB 生成报告
【发布时间】:2013-03-11 16:58:53
【问题描述】:

我正在尝试使用 Linq 从流行的 NorthWind DB 生成以下报告。它应该由CustomerOrderYear分组。

CustomerName    OrderYear    Amount

我必须使用下表CustomerOrderOrder Details。 到目前为止,这就是我所做的。

NorthwindDataContext north = new NorthwindDataContext();

        var query = from o in north.Orders
                    group o by o.Customer.CompanyName  into cg
                    select new
                    {
                        Company = cg.Key,
                        YearGroup = (   from y in cg
                                              group y by y.OrderDate.Value.Year into yg
                                              select new 
                                              {
                                                  Year = yg.Key,
                                                  YearOrdes = yg
                                              }                                             
                                         )
                    };


        foreach (var q in query)
        {
            Console.WriteLine("Customer Name : " + q.Company);
            foreach (var o in q.YearGroup)
            {
                Console.WriteLine("Year " + o.Year);
                Console.WriteLine("Sum " + o.YearOrdes.Sum(yo => yo.Order_Details.Sum( yd=> Convert.ToDecimal(yd.UnitPrice* yd.Quantity))));           
            }

            Console.WriteLine();
        }

它给了我预期的结果。我通过在后端运行 t-sql 进行比较。但是,我有 2 个问题。

  1. 在内部foreach 中,第二条语句生成总和。这是正确的方法吗?还是有更好的?
  2. 如何在 Linq 查询本身中获取 Sum。

【问题讨论】:

    标签: c# .net linq linq-to-sql northwind


    【解决方案1】:

    在单个 LINQ to SQL 查询中得到它:

    var query = from o in north.Orders
                from c in north.Customers.Where(c => c.CustomerID == o.CustomerID).DefaultIfEmpty()
                from d in north.Order_Details.Where(d => d.OrderID == o.OrderID).DefaultIfEmpty()
                group new { o, c, d } by new { o.OrderDate.Value.Year, c.CompanyName } into g
                select new
                {
                    Company = g.Key.CompanyName,
                    OrderYear = g.Key.Year,
                    Amount = g.Sum(e => e.d.UnitPrice * e.d.Quantity)
                };
    

    然后您可以简单地获得结果:

    var results = query.ToList();
    

    或者在获取之前对其进行排序:

    var results = query.OrderBy(g => g.Company).ThenByDescending(g => g.OrderYear).ToList();
    

    我对 LINQ to SQL 查询生成的 SQL 很好奇,所以设置自定义 Log 如下:

    SELECT [t5].[value22] AS [Company], [t5].[value2] AS [OrderYear], [t5].[value] AS [Amount]
    FROM (
        SELECT SUM([t4].[value]) AS [value], [t4].[value2], [t4].[value22]
        FROM (
            SELECT [t3].[UnitPrice] * (CONVERT(Decimal(29,4),[t3].[Quantity])) AS [value], [t3].[value] AS [value2], [t3].[value2] AS [value22]
            FROM (
                SELECT DATEPART(Year, [t0].[OrderDate]) AS [value], [t1].[CompanyName] AS [value2], [t2].[UnitPrice], [t2].[Quantity]
                FROM [dbo].[Orders] AS [t0]
                LEFT OUTER JOIN [dbo].[Customers] AS [t1] ON [t1].[CustomerID] = [t0].[CustomerID]
                LEFT OUTER JOIN [dbo].[Order Details] AS [t2] ON [t2].[OrderID] = [t0].[OrderID]
                ) AS [t3]
            ) AS [t4]
        GROUP BY [t4].[value2], [t4].[value22]
        ) AS [t5]
    ORDER BY [t5].[value22], [t5].[value2] DESC
    -- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 3.5.30729.6387
    

    有点吓人,不是吗?但是如果你仔细观察,有一个标准的LEFT JOIN 用于将所有三个表组合在一起!其余的只是分组、排序和求和。

    【讨论】:

      猜你喜欢
      • 2018-11-14
      • 2019-03-06
      • 2012-02-13
      • 1970-01-01
      • 2013-02-15
      • 2017-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多