結論
データベースからレコードを取得する前に、以下のコードを挿入します。
Dapper.DefaultTypeMap.MatchNamesWithUnderscores = true;
はじめに
Qiita初投稿です。もし当記事が少しでもお役に立った場合は「いいね」を頂けると励みになります。
また、誤った記載があった際はコメント欄にて優しいマサカリをお待ちしています。
環境
- Dapper v1.60.6
- Azure SQL Database V12
- Microsoft.NETCore.App v2.2.3
- Microsoft Visual Studio Community 2017 v15.9.10
詳細
課題
Dapperを使用して取得したレコードの中身をモデルクラスにマッピングしようとした際、
テーブルのカラム名がスネークケース、モデルクラスのプロパティ名がキャメルケースでした。
DataContractAttribute
を使用すればマッピングをうまい具合にやってくれると思ったのですが、
Dapperではうまく機能しないようです。
- SQL Database
personテーブル
first_name | last_name | age |
---|---|---|
Hoge | Fuga | 20 |
- ソースコード
[DataContract(Name = "person")]
class Person
{
[DataMember(Name = "first_name")]
public string FirstName { get; set; }
[DataMemeber(Name = "last_name")]
public string LastName { get; set; }
[DataMemeber(Name = "age")]
public int Age { get; set; }
}
class Program
{
static void Main(string[] args)
{
var connString = "DBの接続文字列";
using (var conn = new SqlConnection(connString))
{
conn.Open();
var sql = "SELECT first_name, last_name, age FROM person;";
var result = conn.Query<Person>(sql).ToList();
}
}
}
- 取得結果
FirstName = null;
LastName = null;
Age = 20;
解決方法
Dapperがカラム名のアンダースコアを無視する設定を追加します。
具体的には、以下のコードをレコードを取得するより前に挿入します。
Dapper.DefaultTypeMap.MatchNamesWithUnderscores = true;
ちなみに、Dapperは大文字小文字はデフォルトで無視するそうなので、上記のプログラムではAge
だけ
マッピングできました。
using (var conn = new SqlConnection(connString))
{
conn.Open();
// ↓ ここに入れる
Dapper.DefaultTypeMap.MatchNamesWithUnderscores = true;
var sql = "SELECT first_name, last_name, age FROM person";
var result = conn.Query<Person>(sql).ToList();
}
最後に
もう一つ、SQL文で素直にカラム名のエイリアスを指定する方法もあります。
SELECT first_name AS FirstName, last_name AS LastName, age AS Age FROM person;
こちらはカラム名とプロパティ名がケース以外も異なる場合にも使えますが、取得したいカラム数が増えると
すべてにエイリアスを指定する必要があり面倒なので、個人的にはDapperの設定を変更する方法が好きです。
DapperはEntity Frameworkと違い軽量かつ導入が簡単で便利なORMですが、意外と日本語情報が少ないので
Dapperをはじめて使用する私のような初心者は頑張りましょう。
参考
https://andrewlock.net/using-snake-case-column-names-with-dapper-and-postgresql/amp/
https://webbibouroku.com/Blog/Article/dapper