LoginSignup
17
19

More than 5 years have passed since last update.

DapperのQueryを使ってマルチマッピングしてみる

Last updated at Posted at 2015-01-21

はじめに

先日、このような投稿をしましたが、もっと楽にマルチマッピングする方法があったので、追記的にまとめていきたいと思います。

下準備と利用環境

以下の環境を利用しています。

  1. C# 5.0
  2. Dapper 1.38.0.0
  3. 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を利用した方が良いと思います。

17
19
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
19