2015年9月4日金曜日

DapperExtensionsを使ってみる2

前回に引き続きDapperExtensionsの小ネタです。
※我ながら遅筆にもほどがある。


今回は、テーブル名や、カラム名がエンティティクラスと異なる場合や、
主キーが複数の場合の対応です。特に主キーは1個にしといてよっと
いいたいところなんですが、会社で業務アプリをさわってる以上、
避けられない、っというか、ほぼ全部ですよってことで。


やり方

前回は複数形のテーブル名を単数形のクラス名に変換するためにすでに準備されている、PluralizedAutoClassMapperをDapperExtensions.DefaultMapperに 設定しましたが、今回はこの部分をカスタムで作ってやる必要があります。


前提条件


こんなテーブルがあったとします。(テーブル名は"syain")


こんなエンティティクラスにMappingしたいです。
public class Person
{
    public int BuilderId { get; set; }
    public string PersonId { get; set; }
    public string Name { get; set; }
}

  • gyousya_id(int)とsyain_id(nvarchar)で複合キー
  • テーブル名syainをPersonに
  • カラム名gyosya_idをBuilderIdに
  • カラム名syain_idをPersonIdに
  • カラム名namaeをNameに


とりあえずやってみる


1.CustomMapperの作成


DapperExtensions.Mapper名前空間にあるClassMapperを継承したCustomMapperを作成します。
01:using DapperExtensions.Mapper;
02:public sealed class CustomClassMapper< T > : ClassMapper< T > where T : class
03:{
04:    public CustomClassMapper()
05:    {
06:        if (typeof(T) == typeof(Person))
07:         {
08:             Table("syain");
09:             Map(x => (x as Person).BuilderId).Column("gyosya_id").Key(KeyType.Assigned);
10:             Map(x => (x as Person).PersonId).Column("syain_id").Key(KeyType.Assigned);
11:             Map(x => (x as Person).Name).Column("namae");
12:        }
13:         AutoMap();
14:    }
15:}

2.DefaultMapperの指定


先ほど作成したCustomMapperをDefaultMapperに指定します。
DapperExtensions.DapperExtensions.DefaultMapper = typeof(CustomClassMapper<>);
この処理はアプリケーション起動時に1回呼ぶだけでおっけーです(前回と一緒です)。 あとはInsert/Update/Deleteも前回と同じ方法で行うことが可能です。


解説・ポイント


  • 01行目:DapperExtensions.Mapper空間のClassMapperを継承したクラスを作成します。
  • 04行目:コンストラクタを作成します。この中にマッピング定義を記載します。
  • 06行目:マッピング対象のクラスを判別します。複数テーブルのマッピングを定義する場合は、ここで切り分けます。
  • 08行目:テーブル名のマッピング定義です。エンティティクラス名とテーブル名が同一の場合は不要です。
  • 09~10行目:主キーが複数の場合の定義です。
  • 11行目:カラム名のマッピング定義です。テーブル名同様、変更がない場合は不要です。
  • 13行目:これはデフォルトのマッピングを追加するメソッドになります。テーブルに「birthday」というカラムがあり、エンティティクラスにも「birthday」という同名のプロパティがある場合必要になります。(今回の例の場合不要ですが、やらないと全定義を記載する必要があるため参考までに記載してあります。)

ポイントとなるのは9~10行目です。今回はカラム名のマッピングとキー指定を同時に行っているため、Column("~").Key(KeyType.Assigned)といった記載になります。
カラム名のマッピングが不要の場合はColumn("~")の部分は不要です。


感想

テーブル数の数だけ、Mapping定義を追加していかなくてはならないので、最初がとても
めんどうです。が、1回設定してしまえば終わりなので(データベースの主キーや名前が変わる
ってことはまずないので)、そこさえ乗り切ってしまえば、さくさく使えるようになって便利です!


2015年5月19日火曜日

DapperExtensionsを使ってみる

Dapperの拡張ライブラリDapperExtensionsについてです。


Dapperとは

 
  すでに解説されてる方がたくさんいらっしゃるので、そちらをご覧ください。


DapperExtensionsとは

  
DapperはORMと冠しているものの、実際はクエリすべて手打ちです。(それがいいんですが)
なんですが、単純なSELECTやINSERT、UPDATE、DELETEはいちいち手打ちするのも面倒!
そんな時に、さくっとかけるようになるDapperの拡張ライブラリです。
 

DapperExtensionsの基本的な使い方


※以下コード部分はC#で記載します。

まず、DapperとDapperExtensionsをNugetなどでプロジェクトに追加します。

PM> Install-Package Dapper
PM> Install-Package DapperExtensions


例えばこんな構成のPersonsテーブルがあったとして、
※主キーはIdentity








こんな、エンティティクラスがあったとします。
public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
}


登録処理を記述するクラスにDapperと、DapperExtensions名前空間をusing します。
 using DapperExtensions;
 using DapperExtensions.Mapper;


今回はテーブル名がPersons、エンティティクラス名がPerson、なので複数形と単数形を変換するルールをプログラム開始時に指定します。
(この処理は1回だけ呼べばOKです。)
DapperExtensions.DapperExtensions.DefaultMapper = typeof(PluralizedAutoClassMapper<>);

Connectionオブジェクトを作成します。

 var connection = new SqlConnection("<接続文字列>");
 connection.Open();

あとは以下ような感じで登録・更新・削除できます。

新規登録(Insert)

connection.Insert(new Person { Name = "テスト太郎" });

更新(Update)

connection.Update(new Person { Id = 1, Name = "テスト太郎更新" });

削除(Delete)

connection.Delete(new Person { Id = 1 });


※connectionのDispose処理記載するの省略してます。

その他

※デフォルトではテーブルの主キーが1つで、IdやPersonIdといった名称の場合にのみ対応します。
複合キーだったりした場合は別途マッピングルールを指定する必要があります。(あとテーブル名とエンティティクラス名が異なる場合とか)
(最初それについて書くつもりだったんですが、だらだらと長くなりそうだったので次回)

雑記

会社で業務システムに携わってるとあれな設計のテーブルも多く(1テーブルカラム100以上とか)、 そういったテーブルに対していちいち単純なSQL文書くのもめんどくさいのでとても重宝してます。

エンティティクラスと条件指定して簡単な検索(SELECT文発行)なんかもできるんですが、これについてはDapperExtensions使わずに、素直にクエリ書いたほうが楽だと思います。条件の指定方法が独特だったり、少し複雑にしようと思うと対応できなかったりします。