Dapperを使って、PostgreSQLの接続クラスを作ってみる

Dapperを使って、PostgreSQLの接続クラスを作ってみます。

まずはDapperの導入から。
といってもNugetから導入するだけです。簡単。
f:id:CreatioVitae:20151216153002p:plain

次に、インポート設定

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Npgsql;
using System.Data;
using Dapper;
using CreatioVitae.Models;
using System.Configuration;

DapperはIDbほにゃらかさんたちに対して拡張メソッドを提供してくれるので、System.Data名前空間もUsingしています。

クラス名は、PostgreSqlConnectという、平凡な名前に設定します。
DAOのbaseクラスをイメージして作るので、abstractクラスとして定義しています。

public abstract class PostgreSqlConnect: IDisposable

propertyとか

#region property

///<summary>
///データベース接続
///</summary>
private IDbConnection Connection{get;set;}

/// <summary>
/// トランザクション
/// </summary>
private IDbTransaction Transaction { get; set; }

/// <summary>
/// 接続状態
/// </summary>
public Boolean IsConnected
{
    get 
    {
        return (Connection.State == ConnectionState.Open);
    }
}

#endregion

データベース接続クラスや、トランザクション管理用のクラスは、privateスコープで設定します。
接続のオープンクローズについては別途メソッド経由で行います。
接続状態のgetプロパティのみ、外部公開します。

次はコンストラクタ

#region constructor
///<summary>
/// コンストラクタ
///</summary>
public PostgreSqlConnect()
{ 
    Connection = new NpgsqlConnection( ConfigurationManager.ConnectionStrings["PostgreSqlConnection"].ConnectionString);

}
#endregion

コンストラクタで、PostgreSQL接続クラスのインスタンスを生成します。
この時、Npgsqlの参照が必要になります。
Npgsqlも、Nugetでゲットできるのでゲットしてしまいましょう。(PostgreSQLのインストールをする時にもゲット出来ますけど。)
DBへの接続文字列は、それぞれ好きな取得方法で良いと思いますが、僕はWeb.Configから取得することが多いです。
Connections.configとかに、定義ファイル分けておくと、複数人で開発するときに素敵ですね。

いよいよメソッド

#region method
/// <summary>
/// コネクションオープン
/// </summary>
public void ConnectionOpen()
{
    if (!IsConnected)
    {
        Connection.Open();
    }
}

/// <summary>
/// コネクションクローズ
/// </summary>
public void ConnectionClose()
{
    if (IsConnected)
    {
        Connection.Close();
    }
}

/// <summary>
/// トランザクション開始
/// </summary>
public void BeginTransaction()
{
    Transaction = Connection.BeginTransaction(IsolationLevel.Serializable);
}

/// <summary>
/// コミット
/// </summary>
public void CommitTransaction()
{
     if (Transaction != null && Transaction.Connection != null)
     {
         Transaction.Commit();
     }
}

/// <summary>
/// ロールバック
/// </summary>
public void RollBackTransaction()
{
    if (Transaction != null && Transaction.Connection != null)
    {
        Transaction.Rollback();            
    }
}

/// <summary>
/// データ抽出
/// </summary>
protected List<t> Select<t>(string query, object parameters) where t : class
{
    return Connection.Query<t>(query, parameters).ToList();

}

/// <summary>
/// データ抽出
/// </summary>
public List<t> Select<t>(string query) where t : class
{
return Connection.Query<t>(query).ToList();
}

/// <summary>
/// SQL実行
/// </summary>
public void Execute(string query)
{
    Connection.Execute(query);
}

/// <summary>
/// SQL実行
/// </summary>
public void Execute(string query, object parameters) 
{
    Connection.Execute(query, parameters);
}
#endregion

コネクションのオープンクローズ、トランザクションの開始、コミット、ロールバックSQL発行@Select用(選択でも射影でも、ご自由に。)、SQL発行@データ登録、編集、削除用 ※ SQL発行はそれぞれparameter有、無版

とりあえず、イニシャルでこのへんまで作ってから、実際にアプリ開発で、必要なメソッドを足していきます。
Sqlについてですが、DapperのようなMicroORMは、SQLの記述は自分でやる必要があります。
(個人的には、SQLの自動生成が苦手なので、この辺もメリットだったりします。)

最近は、アセンブリリソースファイルとかで、Sqlスクリプトに落としたファイルを管理して、読み込むようにしています。





以下は、MicroORM&Dapperについて(自分の中のまとめも兼ねて。)

そもそもMicroORMって?

特徴
  • フルスタックのORMほどの機能は搭載してない。
  • オブジェクトの取り扱う際に、便利な機能がある(データモデルのラップやDB操作のラップ等)

SQLは自分で書く必要がある。
(実行時に必要になるオブジェクトマップやDB操作のお作法とかは受け持ってくれる。)

  • 軽量
  • 早い

↓はDapper.Netの公式から出ているベンチマーク
SQL発行を500回繰り返した時のパフォーマンス計測結果)
github.com
f:id:CreatioVitae:20151216172230p:plain

速度差を見てみると、
SQLDataReaderでの実行と、Dapperでの実行の速度差は2ms。
SQLDataReaderでの実行と、Entity frameworkでの実行の速度差は587ms。

Dapper.Netについて

オープンソース

→ライセンスはApachとMITのデュアルライセンス

作成者

Sam Saffron(Stack Overflowの中の人)
Stack Overflowがさばいているトラフィック量については、以下参照。
http://stackexchange.com/performance