「Dapper」の版間の差分

提供: MonoBook
ナビゲーションに移動 検索に移動
imported>Administrator
(ページの作成:「'''Dapper'''とは、俗にいうMicro ORM。 == 関連項目 == * System.Transactions.TransactionScope == 外部リンク == * 公式サイト - http://code.goog...」)
 
imported>Administrator
 
(3人の利用者による、間の11版が非表示)
1行目: 1行目:
'''Dapper'''とは、俗にいうMicro ORM。
+
'''Dapper'''(読み:だっぱー)とは、[[.NET Framework]]向けの[[マイクロORM]]である。
 +
 
 +
== 概要 ==
 +
Dapperは[[Entity Framework]]や[[Active Record]]のような重量級ORMとは違い、[[SQL]]周りの[[ソースコード]]をまるで[[PHP]]などの[[LL言語]]を使っているかのようにサラサラと書けるという代物である。
 +
 
 +
Dapperはほぼ生の[[SQL]]文を投げると、その結果を[[C Sharp|C#]]の[[クラス]]に自動的に格納(マッピング)してくれる。[[.NET]]標準の[[ADO.NET]]だとクエリ結果は1カラム毎にGetValueメソッドを呼びだして値を取得し、さらに値の型は自前で明示的にキャストして解決するというキチガイ級に面倒でバグの原因になりやすい部分をDapperを使うことでほぼ全自動にできる。
 +
 
 +
なお、Dapperは上記のような単純な結果のマッピングだけを行うものであり、[[LINQ]]を[[SQL]]に変換されたり、[[外部キー]]を頼りに[[リレーション]]を自動解決してくれるなどという重量級[[ORM]]の主要機能といわれるものは一切搭載していない。
 +
 
 +
公式サイトでは[[SQL Server]]と[[SQL Lite]]で動作確認をしているとのことだが、[[MySQL]]([[MySQL Connector/NET]])や[[PostgreSQL]]([[Npgsql]])でも特に問題はないようである。ADO.NETのドライバがある[[データベース]]はほぼ動くと思われる。
 +
 
 +
== 使い方 ==
 +
=== 接続 ===
 +
0、[[NuGet]]からNpgsqlとDapperを入れる。
 +
 
 +
1、Web.configにConnectionStringを設定する。ConnectionStringは[[ソースコード]]に埋め込んでもいいが後から変更が大変なのでWeb.configやApp.configを利用するのが望ましい。Npgsqlを使用しているが他も似たようなもん。
 +
<source lang="xml">
 +
<?xml version="1.0"?>
 +
<configuration>
 +
  <!-- 省略 -->
 +
 
 +
  <system.data>
 +
    <DbProviderFactories>
 +
      <add name="Npgsql Data Provider" invariant="Npgsql" support="FF" description=".Net Framework Data Provider for Postgresql" type="Npgsql.NpgsqlFactory, Npgsql" />
 +
    </DbProviderFactories>
 +
  </system.data>
 +
 
 +
  <connectionStrings>
 +
    <add name="default" providerName="Npgsql" connectionString="Server=localhost; Port=5432; User Id=monobook; Password=; Database=monobook" />
 +
  </connectionStrings>
 +
 
 +
  <!-- 省略 -->
 +
</source>
 +
 
 +
2、「参照」に「System.Configuration」を追加する。
 +
 
 +
3、使ってみる。
 +
[[PGroonga]]を入れた状態で[[全文検索]]を行っても問題ない。
 +
<source lang="csharp">
 +
            var cs = ConfigurationManager.ConnectionStrings["default"].ConnectionString;
 +
            using (var con = new NpgsqlConnection(cs))
 +
            {
 +
                con.Open();
 +
                var memos = con.Query<Memos>(@"select * from memos where content %% '全文検索'");
 +
                foreach (var memo in memos)
 +
                {
 +
                    Console.WriteLine(memo);
 +
                }
 +
            }
 +
</source>
 +
 
 +
=== SELECT ===
 +
<source lang="csharp">
 +
public class UserRawModel
 +
{
 +
    public string user_id { get; set; }
 +
    public string user_name { get; set; }
 +
    // nullable
 +
    public int?  user_age { get; set; }
 +
 +
 
 +
var guid = Guid.NewGuid();
 +
 
 +
var user = connection.Query<UserRawModel>(
 +
  @"select user_age = @user_age, user_id = @user_id"
 +
  , new { user_age = (int?)null, user_id = guid });
 +
 
 +
Console.WriteLine(dog.Count()); // 1
 +
Console.WriteLine(dog.First().user_age); // null
 +
Console.WriteLine(dog.First().user_id); // guid
 +
</source>
 +
 
 +
クエリの際に型を指定しないと結果が[[匿名型]]で自動生成されます。
 +
まるで[[PHP]]のように扱いたいひと向け。
 +
 
 +
[[インテリセンス]]が効かない、参照先・参照元の一覧出力ができないなどの副作用を伴うので乱用はやめた方がいいけど、手軽すぎてやめられない。
 +
前述の理由で[[クラス]]と[[テーブル]]が1対1で問題ない場合は使うべきではないですが、joinした結果を受け取りたい場合などにそのためだけに専用のマッピングクラスを作るのは面倒なのでこれを使うと手軽。
 +
 
 +
クエリー
 +
<source lang="mysql">
 +
select 1 A, 2 B union all select 3, 4;
 +
</source>
 +
結果
 +
<pre>
 +
+---+---+
 +
| A | B |
 +
+---+---+
 +
| 1 | 2 |
 +
| 3 | 4 |
 +
+---+---+
 +
</pre>
 +
 
 +
これを取得するコード。
 +
<source lang="csharp">
 +
var rows = connection.Query("select 1 A, 2 B union all select 3, 4")
 +
    .ToList(); // 配列(リスト)に変換
 +
 
 +
Console.WriteLine(rows[0].A);
 +
Console.WriteLine(rows[0].B);
 +
Console.WriteLine(rows[1].A);
 +
Console.WriteLine(rows[1].B);
 +
</source>
 +
 
 +
=== INSERT ===
 +
パラメータを配列にすると複数行をinsertできます。
 +
<source lang="csharp">
 +
// {1,1},{2,2},{3,3}という3行がinsertされる
 +
// 戻り値は変更された行数
 +
var affected_rows = connection.Execute(
 +
    @"insert MyTable(colA, colB) values (@a, @b)",
 +
    new[] { // パラメータを配列にすると複数行をinsertできます。
 +
        new { a=1, b=1 },
 +
        new { a=2, b=2 },
 +
        new { a=3, b=3 }
 +
    }
 +
);
 +
</source>
  
 
== 関連項目 ==
 
== 関連項目 ==
 
* [[System.Transactions.TransactionScope]]
 
* [[System.Transactions.TransactionScope]]
 +
* [[MySQL Connector/NET]]
  
 
== 外部リンク ==
 
== 外部リンク ==
 
* 公式サイト - http://code.google.com/p/dapper-dot-net/
 
* 公式サイト - http://code.google.com/p/dapper-dot-net/
 
* ソースコード - https://github.com/SamSaffron/dapper-dot-net
 
* ソースコード - https://github.com/SamSaffron/dapper-dot-net
 +
 
{{stub}}
 
{{stub}}

2016年2月24日 (水) 02:18時点における最新版

Dapper(読み:だっぱー)とは、.NET Framework向けのマイクロORMである。

概要[編集 | ソースを編集]

DapperはEntity FrameworkActive Recordのような重量級ORMとは違い、SQL周りのソースコードをまるでPHPなどのLL言語を使っているかのようにサラサラと書けるという代物である。

Dapperはほぼ生のSQL文を投げると、その結果をC#クラスに自動的に格納(マッピング)してくれる。.NET標準のADO.NETだとクエリ結果は1カラム毎にGetValueメソッドを呼びだして値を取得し、さらに値の型は自前で明示的にキャストして解決するというキチガイ級に面倒でバグの原因になりやすい部分をDapperを使うことでほぼ全自動にできる。

なお、Dapperは上記のような単純な結果のマッピングだけを行うものであり、LINQSQLに変換されたり、外部キーを頼りにリレーションを自動解決してくれるなどという重量級ORMの主要機能といわれるものは一切搭載していない。

公式サイトではSQL ServerSQL Liteで動作確認をしているとのことだが、MySQLMySQL Connector/NET)やPostgreSQLNpgsql)でも特に問題はないようである。ADO.NETのドライバがあるデータベースはほぼ動くと思われる。

使い方[編集 | ソースを編集]

接続[編集 | ソースを編集]

0、NuGetからNpgsqlとDapperを入れる。

1、Web.configにConnectionStringを設定する。ConnectionStringはソースコードに埋め込んでもいいが後から変更が大変なのでWeb.configやApp.configを利用するのが望ましい。Npgsqlを使用しているが他も似たようなもん。

<?xml version="1.0"?>
<configuration>
  <!-- 省略 -->

  <system.data>
    <DbProviderFactories>
      <add name="Npgsql Data Provider" invariant="Npgsql" support="FF" description=".Net Framework Data Provider for Postgresql" type="Npgsql.NpgsqlFactory, Npgsql" />
    </DbProviderFactories>
  </system.data>

  <connectionStrings>
    <add name="default" providerName="Npgsql" connectionString="Server=localhost; Port=5432; User Id=monobook; Password=; Database=monobook" />
  </connectionStrings>

  <!-- 省略 -->

2、「参照」に「System.Configuration」を追加する。

3、使ってみる。 PGroongaを入れた状態で全文検索を行っても問題ない。

            var cs = ConfigurationManager.ConnectionStrings["default"].ConnectionString;
            using (var con = new NpgsqlConnection(cs))
            {
                con.Open();
                var memos = con.Query<Memos>(@"select * from memos where content %% '全文検索'");
                foreach (var memo in memos)
                {
                    Console.WriteLine(memo);
                }
            }

SELECT[編集 | ソースを編集]

public class UserRawModel
{
    public string user_id { get; set; }
    public string user_name { get; set; }
    // nullable
    public int?   user_age { get; set; }
}  

var guid = Guid.NewGuid();

var user = connection.Query<UserRawModel>(
  @"select user_age = @user_age, user_id = @user_id"
  , new { user_age = (int?)null, user_id = guid });

Console.WriteLine(dog.Count()); // 1
Console.WriteLine(dog.First().user_age); // null
Console.WriteLine(dog.First().user_id); // guid

クエリの際に型を指定しないと結果が匿名型で自動生成されます。 まるでPHPのように扱いたいひと向け。

インテリセンスが効かない、参照先・参照元の一覧出力ができないなどの副作用を伴うので乱用はやめた方がいいけど、手軽すぎてやめられない。 前述の理由でクラステーブルが1対1で問題ない場合は使うべきではないですが、joinした結果を受け取りたい場合などにそのためだけに専用のマッピングクラスを作るのは面倒なのでこれを使うと手軽。

クエリー

select 1 A, 2 B union all select 3, 4;

結果

+---+---+
| A | B |
+---+---+
| 1 | 2 |
| 3 | 4 |
+---+---+

これを取得するコード。

var rows = connection.Query("select 1 A, 2 B union all select 3, 4")
    .ToList(); // 配列(リスト)に変換

Console.WriteLine(rows[0].A);
Console.WriteLine(rows[0].B);
Console.WriteLine(rows[1].A);
Console.WriteLine(rows[1].B);

INSERT[編集 | ソースを編集]

パラメータを配列にすると複数行をinsertできます。

// {1,1},{2,2},{3,3}という3行がinsertされる
// 戻り値は変更された行数
var affected_rows = connection.Execute(
    @"insert MyTable(colA, colB) values (@a, @b)",
    new[] { // パラメータを配列にすると複数行をinsertできます。
        new { a=1, b=1 },
        new { a=2, b=2 },
        new { a=3, b=3 } 
    }
);

関連項目[編集 | ソースを編集]

外部リンク[編集 | ソースを編集]