-
Notifications
You must be signed in to change notification settings - Fork 0
MS_Dapper
ココで使用したので調査した情報などを纏めました。
Dapper は、Micro-ORM である。
- Micro-ORM は、RDB とはマッピングしないので、ORM ではない。
- 言うなれば、DataMapper とか TableMapper と言った機能。
- 実際、Dapper は、
- 純粋な実行と Bean(POCO) とのマッピングのみ提供する。
- パフォーマンスと使いやすさを念頭に置いて開発されている。
補足(実体は拡張メソッド): Dapper は
IDbConnectionに対する拡張メソッドの集合であり、
ADO.NETを置き換えるものではなく、その上に薄く乗るものである。await using var cn = new SqlConnection(cs); var users = await cn.QueryAsync<User>( "SELECT Id, Name FROM Users WHERE DeptId = @deptId", new { deptId });このため、
- 接続・トランザクション・接続プールの扱いは ADO.NET と同じ
(ADO.NETデータプロバイダの接続文字列)- 発行される SQL は自分が書いたものそのままで、ブラックボックスにならない
という性質を持つ。Entity Frameworkとの
最大の違いはこの点にある。
- 基本的には無い。
- 生 SQL を実行する機能のみ提供される。
- 以下の拡張ライブラリが該当機能を提供している。
パラメタライズド・クエリ機能はアリ。
- ADO.NET よりパラメタライズド処理が書き易い。
- IN 句に含めるリストに値をバインドする機能などもある。
補足(IN 句の展開): 匿名型のプロパティに配列やリストを渡すと、
Dapper がIN (@p1, @p2, ...)に自動展開する。var rows = await cn.QueryAsync<User>( "SELECT * FROM Users WHERE Id IN @ids", new { ids = new[] { 1, 2, 3 } }); // 括弧は書かないただし、要素数が変わるたびに別の SQL テキストになるため、
SQL Server のプラン キャッシュが分断される点には注意
(SQL Server アドホック クエリ問題の監視)。
件数が多い場合はテーブル値パラメータや一時テーブルを検討する。
トランザクション処理に対応する。
以下のように処理すると良い。
-
Razor での Dapper サンプル(トランザクション使って Update)
https://gist.github.com/kiyokura/7185408 -
using ステートメントを使えば
SqlTransactionの明示的なRollbackは不要 - プログラマーな日々
http://blog.jhashimoto.net/entry/20111008/1318231481
未コミットのものはロールバックになるので、try-catch は不要。
using(var tr = cn.BeginTransaction())
{
cn.Execute("・・・・", ・・・, tr);
tr.Commit();
}補足:
Dispose時に未コミットのトランザクションが
ロールバックされるのは ADO.NET(SqlTransaction)の仕様であり、
Dapper 固有の機能ではない。
なお、cn自体もusing(await using)で確実に破棄し、
接続プールへ返却すること。
- ストアド プロシージャを実行可能。
補足:
commandType: CommandType.StoredProcedureを指定する。
出力パラメータや戻り値はDynamicParametersで受け取る。var p = new DynamicParameters(); p.Add("@id", id); p.Add("@count", dbType: DbType.Int32, direction: ParameterDirection.Output); await cn.ExecuteAsync("usp_Something", p, commandType: CommandType.StoredProcedure); int count = p.Get<int>("@count");ストアド プロシージャ側の詳細はストアド プロシージャを参照。
結果セットと Bean(POCO) をマッピングする機能。
-
Queryメソッドでは、IEnumerable<dynamic>型に格納される。 -
Query<T>メソッドでは、T 型の Bean(POCO) にマッピングして、格納される。 - 列名に別名を付与する場合は、
AS句を使用すれば良い。 - 大文字・小文字は関係なくマッピングする。
- 別途マッピング ルールを型毎に設定することが可能。
- ADO.NET 型付
DataSetの場合よりマッピング処理が書き易い。
移行メモ(誤字): 元ページの
IEnumrable<Dynamic>は
正しくはIEnumerable<dynamic>。
補足(アンダースコア付き列名):
USER_NAMEのような列名を
UserNameプロパティにマッピングしたい場合は、
起動時に以下を 1 度だけ設定する。Dapper.DefaultTypeMap.MatchNamesWithUnderscores = true;
主に、ADO.NET の IDbConnection に拡張メソッドを追加している。
以下の様な CRUD ヘルパーがある。
-
SQL を書かずして更新処理を実装する。
-
テーブルに対応した Bean(POCO) が必要になる。
-
デフォルトでは以下の条件に合致している必要がある。
- テーブルの主キーが 1 つ
-
Idや****Idといった名称
-
参考
- hollycot: DapperExtensions を使ってみる
http://hollycot.blogspot.jp/2015/05/dapperextensions.html - hollycot: DapperExtensions を使ってみる2
http://hollycot.blogspot.jp/2015/09/dapperextensions.html
- hollycot: DapperExtensions を使ってみる
詳細不明。
詳細不明。
補足:
Dapper.Contribは Dapper の公式リポジトリに含まれる拡張で、
[Table]/[Key]属性を付けた POCO に対して
Get<T>/Insert/Update/Delete/GetAll<T>を提供する。
単純な CRUD だけなら SQL を書かずに済むが、
DapperExtensionsと同様に主キーが単一であることなどの制約がある。
Dapper.Rainbowは同じく公式リポジトリ内の
テーブル単位のヘルパーだが、現在はほとんど使われていない。
以下を参考にすると、上記は微妙らしい。
- neue cc - Micro-ORM と C#(と Dapper カスタマイズ)
http://neue.cc/2012/12/11_390.html
ココの処理の内容を見ると、
-
ExpressionHelperを引数に取る拡張メソッド
≒ LINQ を処理可能な拡張メソッド
で SQL を生成している。
余談:
...と言うことで、
パラメタセットによって、SQL 定義を動的に編集する方法ではなさそう。
Dapper は、パラメタセットは Bean(POCO) のプロパティ ≒ 固定なので、
別の方法で SQL 編集するしか無く、Parameter によって SQL 定義を編集する、
動的パラメタライズド・クエリに組み込むことが不可能だった。
MiniProfiler を使用してログ出力処理を実装できる。
- Output the tracelog using Dapper. · Issue #45 · OpenTouryoProject/MultiPurposeAuthSite
https://github.com/OpenTouryoProject/MultiPurposeAuthSite/issues/45
補足(発行 SQL の確認): MiniProfiler の
ProfiledDbConnectionで
接続をラップすると、Dapper 経由の SQL も含めて記録できる。
DB 側から見る場合は
SQLプロファイラ(SQLトレース)や
クエリ ストア(SQL Server のログ)を使う。
以下のように ORM できるが、
- dapper dot net - 1 対多のテーブルをコレクション プロパティにマッピングする - いちろぐ
http://ichiroku11.hatenablog.jp/entry/2015/04/13/234109 - Code, code and more code.: Exploring Tuples as a Library Author
http://blog.marcgravell.com/2017/04/exploring-tuples-as-library-author.html
BA(ビジネス・アプリケーション)ではほぼ、採用しない方式。
- スキーマ構造に合わせたデータ保持をしない。
- 論理データ独立性が重要。
- また、コードが複雑化する。
- プログラム側での OrderBy で性能が劣化する。
補足(マルチマッピング): Dapper で階層構造を組む場合は、
Query<TFirst, TSecond, TReturn>にsplitOnを指定する。var rows = await cn.QueryAsync<Order, Customer, Order>( @"SELECT o.*, c.* FROM Orders o JOIN Customers c ON c.Id = o.CustomerId", (o, c) => { o.Customer = c; return o; }, splitOn: "Id");1 対多を組む場合は行が重複して返るため、
アプリ側でGroupByして畳み込む必要がある。
元ページが指摘しているとおり、この方式は
コードが複雑化しやすく、件数が増えると性能も落ちる。
Dapper の Query<dynamic>() の戻り値を JSON へ変換して、
サーバーを JSON 吐く土管にする場合、以下のようにできる。
-
Dapper の
Query<dynamic>()の戻りを ASP.NET MVC の JsonResult でいい感じで返す - きよくらの備忘録
http://kiyokura.hateblo.jp/entry/2014/12/04/000818 -
Dapper の
Query<dynamic>()の結果セットのフィールド名を取得する - きよくらの備忘録
http://kiyokura.hateblo.jp/entry/2016/12/09/131602
-
Dapper.Net を使ってみる - けさらんぱさらん
http://d.hatena.ne.jp/cer1974/20120205/1328450442 -
Dapper で Oracle の NUMBER と .NET の Boolean をマッピングする - きよくらの備忘録
http://kiyokura.hateblo.jp/entry/2013/11/08/015826 -
Getting started with Dapper – logically illogical
https://takaloy.wordpress.com/2015/05/10/getting-started-with-dapper/ -
Dapper – Micro ORM for Oracle and Microsoft .NET
https://blog.vijay.name/2012/07/dapper-micro-orm-for-oracle-and-microsoft-net/
補足: Dapper は
IDbConnectionの拡張であるため、
ADO.NETデータプロバイダさえあれば
どの DBMS でも動作する。
ただし、パラメータ記法(SQL Server は@、Oracle は:)や
型のマッピング(Oracle のNUMBER(1)とboolなど)は
DBMS 依存なので、クロスDB対応の観点では注意が要る。
-
ORM とか dapper dot net についてお話させていただきました - きよくらの備忘録
http://kiyokura.hateblo.jp/entry/20131014/p1 -
Dapper の簡単な使い方メモ (Dapper .NET, Micro ORM, 速い) - いろいろ備忘録日記
http://devlights.hatenablog.com/entry/2014/02/02/000000- Dapper .NET のサンプル
https://gist.github.com/devlights/8779382
- Dapper .NET のサンプル
-
C# + MySQL + Dapper で軽量 O/R Mapper | Aiming 開発者ブログ
https://developer.aiming-inc.com/programming/csharp-mysql-dapper/ -
How to work with Dapper in C# | InfoWorld
http://www.infoworld.com/article/3025784/application-development/how-to-work-with-dapper-in-c.html -
データ ポイント - Dapper、Entity Framework、およびハイブリッド アプリ
https://learn.microsoft.com/ja-jp/archive/msdn-magazine/ -
Dapper(GitHub)
https://github.com/DapperLib/Dapper
補足(最新化): Dapper は 2022 年に
Stack Overflow 傘下から DapperLib organization へ移管され、
現在も活発にメンテナンスされている。
ネイティブ AOT やDapperAOT(ソース ジェネレータ版)への対応も進んでいる。
ADO.NET vs ORM (Entity Framework, Dapper)
Tags: 移行, データアクセス, .NET開発, ADO.NET
このWikiは「Open棟梁Project」,「OSSコンソーシアム 開発基盤部会」によって運営されています。