0

次のように定義された「データベース」があるとします。

// Baked goods vendors
   var vendor = new[] {
    new { ID = 1, Baker = "Pies R Us", StMnemon = "NY", Items = 8, Rating = 9 },
    new { ID = 2, Baker = "Mikes Muffins", StMnemon = "CA", Items = 5, Rating = 9 },
    new { ID = 3, Baker = "Best Bakers", StMnemon = "FL", Items = 2, Rating = 5 },
    new { ID = 4, Baker = "Marys Baked Treats", StMnemon = "NY", Items = 8, Rating = 7 },
    new { ID = 5, Baker = "Cool Cakes", StMnemon = "NY", Items = 4, Rating = 9 },
    new { ID = 6, Baker = "Pie Heaven", StMnemon = "CA", Items = 12, Rating = 9 },
    new { ID = 7, Baker = "Cakes N More", StMnemon = "GA", Items = 6, Rating = 8 },
    new { ID = 8, Baker = "Dream Desserts", StMnemon = "FL", Items = 2, Rating = 7 }
};

// Locations
var location = new[] {
    new {ID= 1, State = "New York", Mnemonic = "NY"},
    new {ID= 2, State = "Massachusetts", Mnemonic = "MA"},
    new {ID= 3, State = "Ohio", Mnemonic = "OH"},
    new {ID= 4, State = "California", Mnemonic = "CA"},
    new {ID= 5, State = "Florida", Mnemonic = "FL"},
    new {ID= 6, State = "Texas", Mnemonic = "TX"},
    new {ID= 7, State = "Georgia", Mnemonic = "GA" }
};

SQL クエリと同等のクエリを作成したい:

SELECT   State, Rating, SUM(Items) AS 'Kinds'
FROM     vendor, location
WHERE    vendor.StMnemon = location.Mnemonic
GROUP BY State, Rating

このクエリで注目すべき点は次の 2 つです。

  1. GROUP BY には複数のテーブルが含まれます。
  2. 結果には、グループ化基準に表示されない列の合計が含まれます。

複数のテーブルによるグループ化group-by にない列の合計に関する投稿で解決策を見てきました。問題は、両方を組み合わせてもリレーショナル クエリが実際には複製されないことです。

次のコードを使用して、LINQ で複製しようとしています。

var query = from v in vendor
           join l in location
           on v.StMnemon equals l.Mnemonic
           orderby v.Rating ascending, l.State
           select new { v, l };

var result = from q in query
           group q by new { 
               s = q.l.State, 
               r = q.v.Rating
/* ==> */    , i = q.v.Items
           } into grp
        select new 
        {
            State = grp.Key.s,
            Rating = grp.Key.r
/* ==> */ , Kinds = grp.Sum(k => grp.Key.i)
        };

これにより、次の結果が得られます。

=================================
State           Rating  Kinds
Florida         5       2
Florida         7       2
New York        7       8
Georgia         8       6
California      9       5
California      9       12
New York        9       8
New York        9       4
=================================

一方、上記の SQL クエリは次の結果を返します。

=========================
State       Rating  Kinds
Florida     5       2
Florida     7       2
New York    7       8
Georgia     8       6
California  9       17
New York    9       12
=========================

不一致は、グループ化基準以外に追加の列を配置する場所がないように見えるためです。もちろん、グループ化された結果が変わります。上記のコードの/* ==> */コメントで示される 2 行をコメント アウトすると、SQL の結果と同じグループ化が得られますが、当然、含めたい合計フィールドが削除されます。

LINQ で複数のテーブルをグループ化し、グループ化された結果を変更せずに追加の条件を含めるにはどうすればよいですか?

4

2 に答える 2

2

このようなものは、SQLクエリと同じものを返すようです。

var result = from v in vendor
             from l in location
             where l.Mnemonic == v.StMnemon
             group v by new { l.State, v.Rating } into grp
             orderby grp.Key.Rating ascending, grp.Key.State
             select new {State = grp.Key.State, Rating = grp.Key.Rating, Kinds = grp.Sum(p=>p.Items)};

foreach (var item in result)
        Console.WriteLine("{0}\t{1}\t{2}", item.State, item.Rating, item.Kinds);
于 2012-11-20T21:53:43.833 に答える
2

グループ外で集計を行うことができます。

var query = from v in vendor
           join l in location
           on v.StMnemon equals l.Mnemonic
           orderby v.Rating ascending, l.State
           select new { v, l };

var result = from q in query
           group q by new { 
               s = q.l.State, 
               r = q.v.Rating
           } into grp
        select new 
        {
            State = grp.Key.s,
            Rating = grp.Key.r,
            Kinds = grp.Sum(g => g.Items)
        };

グループ化は理解するのが少し難しいです-それIGroupingは1つのプロパティを持つを返します- Key。そのグループ内の実際のアイテムは、グループGetEnumerator()をそれらのアイテムのコレクションとして扱うことができる関数によって返されます。つまり、そのグループ内のアイテムに対して集計を行うことができます。

于 2012-11-20T21:54:01.377 に答える