SQLiteにDapperで読み書きする

C#SQLite読み書きするときに使うORMを探していたところ、Dapper.NetというORMを見つけた。

github.com

このDapper.Netがとても使いやすかったので紹介がてら、使い方のメモを残そうかと思う。

事前準備

  1. Nugetから「Depper dot net」をインストールする
  2. Nugetから「System.Data.SQLite」をインストールする

  3. 以下のような「user」テーブルを作成します。

CREATE TABLE user(
  id integer primary key,
  name text,
  age integer
);

SELECT文

とりあえずまずはSELECTができる事を確かめてみる。
先ほど定義したuserテーブルに適当なデータを3件ほど挿入しておく。

上記のUserテーブルを格納するクラスを作成する。
プロパティ名称はテーブル定義のカラム名称と合わせ、integer型の主キーはlong?で定義する。

public class User
{
    public long? ID { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
}

usingを追加する

using Dapper;

SELECT文を投げる処理を追加する。

public static IEnumerable<User> GetAll()
{
    var config = new SQLiteConnectionStringBuilder() 
    {
        DataSource = @"..\..\..\testdb.db" 
    };
    using (var connection = new SQLiteConnection(config.ToString()))
    {
        connection.Open();
        return connection.Query<User>(@"select * from user");
    }
}

プロパティメンバーを表示するためのToStringを追加する。

public override string ToString()
{
    return string.Format("ID={0}, Name={1}, Age={2}", ID, Name, Age);
}

SELECTしたデータを表示してみる

static void Main(string[] args)
{
    User.GetAll().ForEach(x => Console.WriteLine(x));

    Console.ReadKey();
}

ちゃんとデータが取得できた。

f:id:hkou:20150719082404p:plain

INSERT文

SELECT処理と被るので、コネクションを返す部分をメソッドに分割する

private static SQLiteConnection GetConnection()
{
    var config = new SQLiteConnectionStringBuilder()
    {
        DataSource = @"..\..\..\testdb.db"
    };
    return new SQLiteConnection(config.ToString());
}

Insert処理
値は「@名前」形式で指定する。

public static void Insert(User user)
{
    using (var connection = GetConnection())
    {
        connection.Open();
        using (var tran = connection.BeginTransaction())
        {
            try { 
                connection.Execute("insert into user(name, age) values(@name, @age)", user, tran);
                tran.Commit();
            }
            catch (Exception)
            {
                tran.Rollback();
            }
        }
    }
}

UPDATE文

UPDATE文もInsert文と同じくExecuteメソッドを呼び出して実行する。

public static void UpdateById(User user)
{
    using (var connection = GetConnection())
    {
        connection.Open();
        using (var tran = connection.BeginTransaction())
        {
            try
            {
                connection.Execute("update user set name=@name, age=@age where id=@id", user, tran);
                tran.Commit();
            }
            catch (Exception)
            {
                tran.Rollback();
            }
        }
    }
}

WPFアプリケーションからWinFormsのコントローラを使う

WPFアプリケーションを作成していると、WPFにはないけど、WinFormsにはあるコントロールをどうしても使いたいという場面が出てきます。今回はそんなときにWPFアプリケーションからWinFormsコントローラを使用する方法を解説します。

System.Windows.Formsへの参照の追加

プロジェクトの参照設定を右クリックして「参照の追加」を選択します。

f:id:hkou:20150630215430p:plain

参照マネージャーのウィンドウが表示されるので、フレームワークから「System.Windows.Forms」にチェックを付けます。 f:id:hkou:20150630215543p:plain

WindowsFormsIntegration.dllへの参照追加

参照マネージャーの参照ボタンを押下します f:id:hkou:20150630215950p:plain

ファイル選択ダイアログが表示されるので「WindowsFormsIntegration.dll」を選択します。

※このDLLは.Netのインストール先フォルダにあります。

例:C:\Windows\Microsoft.NET\Framework64\v4.0.30319\WPF

XAMLの修正

名前空間の追加

WinFormsコントロールを参照するために名前空間を追加します

<Window x:Class="UsingWinFormsTest.Views.MainWindow"

   xmlns:winform="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
   …>

コントロールの追加

今回はWinFormsのLabelを使用します

<Grid>
    <WindowsFormsHost>
        <winform:Label Text="Windows Forms Label" />
    </WindowsFormsHost>
</Grid>

実行

実行してみます。ちゃんとLabel表示されることが確認できました。

f:id:hkou:20150630220614p:plain

ViewModelから他のViewを開く

概要

ViewModelから他のViewを開きたいとき、WinFormの場合だとFormのインスタンスを生成してShowDialog()を呼び出していたと思うが、MVVMパターンに準拠するとViewModelからViewに依存することになってしまう為、その方法は使用できない。

ではどうするかというとMessageパターンというものを使用して、ViewModel→Message→ViewというようにMessageを介すことでViewに依存関係を作らないようにするのだ。
これを普通に書くと結構なコード量になるが、LivetにはちゃんとMessageパターン用のクラスが用意されている。

やりたいこと

MainWindowからSubWindowを表示する

MainWindowViewModel.cs

MainWindowのViewModelからSubWindow表示用のメッセージを送る。
TransitionMessageコンストラクタの第一引数には表示するWindowのViewModelを渡し、第2引数にはメッセージキーを渡す。
メッセージキーはメッセージを受け取った時の振り分けに使用される。

using Livet;
using Livet.Messaging;

public void ShowSubWindow()
{
    Messenger.Raise(new TransitionMessage(new SubWindowViewModel(), "SubViewMessageKey"));
}

MainWindow.xaml

xamlにはメッセージを受け取り、SubViewを表示する旨を記述する。

xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:l="http://schemas.livet-mvvm.net/2011/wpf"

<i:Interaction.Triggers>
    <l:InteractionMessageTrigger MessageKey="SubViewMessageKey" Messenger="{Binding Messenger}">
        <l:TransitionInteractionMessageAction WindowType="{x:Type v:SubWindow}" Mode="Modal"/>
    </l:InteractionMessageTrigger>
</i:Interaction.Triggers>