C# + MS Accessで、OLE DB接続にてDapperを使う

C# + MS Access 環境で型付Datasetを使っていたのですが、Datasetのデザイナなどがツライです。

そこで、DapperをOLE DB接続で試してみたところ動作したため、いろいろと試してみました*1
StackExchange/dapper-dot-net

なお、Dapperの基本的な使い方については、以下のBlogとスライドが参考になりました。
ORMとかdapper dot netについてお話させていただきました - きよくらの備忘録

 

環境

 

準備

スライドにもある通り、NuGetでプロジェクトに追加して、コードの中で using Dapper; するだけです。

あとは、ビルドのプラットフォームターゲットを x86 にすれば、MS Accessの32bit版でも問題なく動作するかと思います。

 

MS Accessで使ってみる

ほぼスライドのままですが...。

ここで紹介している以外のサンプルコードとしては、DapperのTestsフォルダの中にある Tests.cs が参考になります。
dapper-dot-net/Tests/Tests.cs at master · StackExchange/dapper-dot-net · GitHub

MS Accessだからといって、SQL Serverのサンプルとかと書き方は変わりません。

 

接続

System.Data.OleDb.OleDbConnection に接続文字列を渡し、中で Open() Close() すればOKです。

接続文字列はSettings.settingsに設定したものを使うか、そのままの文字列を渡します。

using (var cn = new System.Data.OleDb.OleDbConnection(new Connection().ConnectionString))
{
    cn.Open()
    // hoge
    cn.Close()
}

public class Connection
{
    public string ConnectionString { get; private set; }
    public Connection()
    {
        //  接続文字列はSettings.settingsに設定したものを使える(Properties.Settings.Default)が、今回は自前で文字列を渡してみた
        var path = System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "sample.accdb");
        ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path;
    }
}

 

SELECT
インテリセンスがきかない書き方

インテリセンスはきかないですが、ささっと書いて使うにはこれで十分な気がしました。

const string SQLSelect = @"SELECT * FROM Item WHERE ItemName = @ItemName";
const string SelectParameter = "りんご";

var results = cn.Query(SQLSelect, new { ItemName = SelectParameter });

 

インテリセンスがきく書き方

型を用意しておけば、インテリセンスがきくようになります。

const string SQLSelect = @"SELECT * FROM Item WHERE ItemName = @ItemName";
const string SelectParameter = "りんご";

//  この第二引数にはインテリセンスはきかない
var results = cn.Query<Item>(SQLSelect, new { ItemName = SelectParameter });

//  ここでインテリセンスがきく
var msgs = results.Select(a => a.ID + a.ItemName);
Console.WriteLine(string.Join(Environment.NewLine, msgs));


//  用意した型
public class Item
{
    public int ID { get; set; }
    public string ItemName { get; set; }
}

 

INSERT
var sql = @"INSERT INTO Item(ItemName) VALUES(@ItemName)";
var count = cn.Execute(sql, new { ItemName = DateTime.Now.Millisecond.ToString() });

 

UPDATE
var sql = @"UPDATE Item SET ItemName = 'シナノゴールド' WHERE ID = @Id";
var count = cn.Execute(sql, new { Id = 1 });

 

トランザクション

ExecuteメソッドtransactionパラメーターSystem.Data.IDbTransactionオブジェクト を渡せばトランザクションになります。

using (var tr = cn.BeginTransaction())
{
    var insert = @"INSERT INTO Item(ItemName) VALUES(@ItemName)";
    cn.Execute(insert, new { ItemName = DateTime.Now.Millisecond.ToString() }, transaction: tr);

    var update = @"UPDATE Item SET ItemName = 'シナノゴールド' WHERE ID = @Id";
    cn.Execute(update, new { Id = 1 }, transaction: tr);

    tr.Commit();
}

 

コード

GitHubに上げておきました。
CSharp-Sample/DapperApp at master · thinkAmi/CSharp-Sample

 

その他の参考

*1:Entity Frameworkは動かなそうなので、やめておきました - c# 4.0 - How to use Entity framework for MS Access database - Stack Overflow