#はじめに
先日、このような投稿をしましたが、もっと楽にマルチマッピングする方法があったので、追記的にまとめていきたいと思います。
#下準備と利用環境
以下の環境を利用しています。
- C# 5.0
- Dapper 1.38.0.0
- System.Data.SQLite 1.0.94.0
また、以下のようなテーブルスキーマを使います。
CREATE TABLE Categories (
Id INTEGER PRIMARY KEY,
Name TEXT NOT NULL
UNIQUE
);
CREATE TABLE Items (
Id INTEGER PRIMARY KEY,
CategoryId INTEGER NOT NULL
REFERENCES Categories (Id) ON UPDATE CASCADE
ON DELETE CASCADE,
Name TEXT NOT NULL
UNIQUE
);
また、マップ先は以下の通りです。
public class Category
{
public long? Id { get; set; }
public string Name { get; set; }
}
public class Item
{
public long? Id { get; set; }
public long? CategoryId { get; set; }
public string Name { get; set; }
}
#実際に使ってみる
SELECT *
FROM Categories
INNER JOIN
Items ON Categories.Id = Items.CategoryId;
上記のようなクエリを先に定義した、Categoryクラスと、Itemクラスにマップして、匿名クラスを生成するには以下のように書きます。
internal class Program
{
private static void Main(string[] args)
{
SQLiteConnectionStringBuilder bld = new SQLiteConnectionStringBuilder
{
DataSource = "Sample.db3",
ForeignKeys = true,
};
using (SQLiteConnection conn = new SQLiteConnection(bld.ToString()))
{
var ret =
conn.Query("select * from Categories inner join Items on Categories.Id=Items.CategoryId ",
(Category c, Item i) => new {i.Id, CategoryName = c.Name, i.Name});
foreach (var elem in ret)
{
Console.WriteLine(elem);
}
}
}
}
このケースの場合、splitOnは、デフォルトのIdとなっているので指定せずに済みますが、もし違う場合は、適宜調整が必要になります。
その他の注意する点に関しては、先日のエントリの、ここらへんとか、このへんを参考にしてください。
#まとめ
先日のQueryMultiple経由の場合に比して、GridReader経由で取得する必要がない分、楽にすっきりかけると思います。
ただ、GridReaderは結果をBufferしてくれるので、逆に様々な形で繰り返し同じテーブルを相手にする場合は、QueryMultipleを利用した方が良いと思います。