0

NorthWindLinq を使用して、一般的な DB から次のレポートを生成しようとしています。Customer、でグループ化する必要がありますOrderYear

CustomerName    OrderYear    Amount

次の表を使用する必要がCustomerありOrderますOrder 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. Innerforeachでは、2 番目のステートメントが合計を生成します。適切なアプローチですか?それとももっと良いものがありますか?
  2. Linq クエリ自体で Sum を取得する方法。
4

1 に答える 1

0

単一の 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 JOIN3 つのテーブルすべてを組み合わせるために使用される標準があります。残りはすべて、グループ化、並べ替え、および合計です。

于 2013-03-11T17:25:13.723 に答える