dapper dot net - 1対多のテーブルをコレクションプロパティにマッピングする
いつものごとくタイトルが微妙な気もしますが、やりたいことは「DBに注文テーブルと注文明細テーブルがあって、注文明細のコレクションを持っている注文にマッピングしたい」といった感じのことです。
てことでマッピングするクラスです。
// 注文 class Order { public int Id { get; set; } public string Seat { get; set; } // テーブル番号とかカウンター番号のこと // 注文明細のコレクション public List<OrderDetail> Details { get; set; } } // 注文明細 class OrderDetail { public int Id { get; set; } public int OrderId { get; set; } public string Menu { get; set; } // 注文したメニューの名前 }
Order.DetailsプロパティにOrderDetailを入れてOrderのコレクションを取得したいと思います。他にいい方法があるのかわかりませんが、とりあえず試したサンプルコードを残しておきます。
テストデータを用意します。
connection.Execute(@" -- 注文テーブルを作成 create table #Order(Id int, Seat nvarchar(50)); -- 注文明細テーブルを作成 create table #OrderDetail(Id int, OrderId int, Menu nvarchar(50)); insert into #Order(Id, Seat) values(1, N'1番テーブル'), (2, N'2番カウンター'); -- 1番テーブルのお客さんが純けい、ねぎま、しろを注文 insert into #OrderDetail(Id, OrderId, Menu) values(1, 1, N'純けい'), (2, 1, N'ねぎま'), (3, 1, N'しろ'); -- 2番カウンターさんが串かつとねぎまを注文 insert into #OrderDetail(Id, OrderId, Menu) values(4, 2, N'串かつ'), (5, 2, N'ねぎま');"); }
純けいを食べたくなりましたが、データを取り出します。
var orders = connection.Query<Order, OrderDetail, Tuple<Order, OrderDetail>>(@" select * from #Order inner join #OrderDetail on #Order.Id = #OrderDetail.OrderId;", // 一旦Tupleで受ける (order, orderDetail) => Tuple.Create(order, orderDetail)) // Order.Idでグルーピング .GroupBy( tuple => tuple.Item1.Id, (key, tuples) => { var order = tuples.First().Item1; // OrderDetailのコレクションを設定 order.Details = tuples.Select(tuple => tuple.Item2).ToList(); return order; }); foreach (var order in orders) { Console.WriteLine(order.Seat); order.Details.ForEach(detail => Console.WriteLine("\t" + detail.Menu)); } /* 1番テーブル 純けい ねぎま しろ 2番カウンター 串かつ ねぎま */
一旦Tupleで各レコードを受けてOrder.Idでグルーピングしてから、Order.DetailsにOrderDetailのコレクションを設定しています。dapper dot netではなくてLINQのサンプルになってしまった気もしますが以上です。
純けい食べたいです。