豚吐露@wiki

パスカルケースのクラス名とスネークケースのテーブル名を関連付けたい

最終更新:

Bot(ページ名リンク)

- view
管理者のみ編集可

パスカルケースのクラス名とスネークケースのテーブル名を関連付けたい

Windows 7 Professional
Visual Studio 2013 Professional
.Net Framework 4.5
ASP.NET MVC 5.1.2
Web API 2.1
Entity Framework 6.1.0 ※以降EF6
PostgreSQ L9.3.5.1

本来、DbContextでは、Tableアノテーションで指定が無い場合、クラス名と一致するテーブル名を参照する。
が、以下のようなケースもある。
  • テーブル名はスネークケース(hoge_fuga_master)だけど、クラス名はパスカルケース(HogeFugaMaster)

こう言う時に、全モデルにTableアノテーション付けて、正式名称を教えてあげてもいいんだけど...さすがにアホくさいのでDbContextで吸収してやる方法をとる。

見たら分かる、DbContextを継承したDB接続用のクラス。
e.g.) DbContext
  1. public class HogedbContext : DbContext
  2. {
  3. public DbSet<Report> report { get; set; }
  4.  
  5. public string schema { get; set; }
  6.  
  7. public HogedbContext(string schemaName = "dbschema")
  8. {
  9. this.schema = schemaName;
  10. }
  11.  
  12. protected override void OnModelCreating(DbModelBuilder modelBuilder)
  13. {
  14. modelBuilder.Conventions.Add(new HogedbConvention(this.schema));
  15. base.OnModelCreating(modelBuilder);
  16. }
  17. }
3行目は、DbSetなので置いといて。
5行目は、schema名持っとくメンバを作っといた。コンストラクタでschema名指定されたら、そいつ使うようにしてる。
12行目、今回のキモ。OnModelCreating()をoverrideして、自分で作ったConventionクラスを与えてやる。
14行目、実際にConventionを与えているところ。HogedbConventionが自分で作ったConventionクラス。

見慣れないこいつは、DbContextにDB接続時の条件を色々与えてやれるクラス。
Conventionなので慣例って意味ですね。DbContextに慣例を与えてやるんです。
e.g.) Convention
  1. class HogedbConvention : Convention
  2. {
  3. public HogedbConvention(string schema)
  4. {
  5. this.Types().Configure(c => c.ToTable(pascal2snake(c.ClrType.Name), schema));
  6.  
  7. this.Properties().Configure(p => p.HasColumnName(p.ClrPropertyInfo.Name.ToLower()));
  8. }
  9.  
  10. static private string pascal2snake(string src)
  11. {
  12. string pattern = "([^_])([A-Z])";
  13. string replacement = "$1_$2";
  14.  
  15. return Regex.Replace(Regex.Replace(src, pattern, replacement), pattern, replacement).ToLower();
  16. }
  17. }
3行目、コンストラクタ。引数でschema名受け取るようにした。
5行目、ToTableでなんちゅうTable名で、なんちゅうSchema名のtableに接続するかを指定する。
schema名指定しないと、強制的にschema名が『dbo』になっちゃうのがイヤですよね。(´・ω・`)
『c』はConventionTypeConfiguration。ClrTypeに当該モデルのTypeを持ってる。このnameをスネークケースに変換して設定してる。
※Typeはhoge.GetType()で取れるヤツ。
7行目、HasColumnNameでcolumn名を指定してる。
『p』はConventionPrimitivePropertyConfiguration。ClrPropertyInfoに当該プロパティのPropertyInfoが入ってるので、小文字化してcolumn名にしてる。
※PropertyInfoは、hoge.GetType().GetProperty("【プロパティ名】")で取れるヤツね。
10~17行目、パスカルケースからスネークケースに変換するmethod。大文字が並んでると全部が全部スネークケースにならんから、しゃあなしに2回『アンダーバー以外+大文字を見つけたら大文字の前にアンダーバーを入れる』って正規表現をやってる。
で、正規表現で処理した後、全部小文字化してる。

以上で、
  • パスカルケースのクラス名を変換して、スネークケースのテーブル名としてアクセスする
  • プロパティ名を小文字化して、カラム名としてアクセスする

が実現できる。



更新日: 2014年11月27日 (木) 16時27分33秒

名前:
コメント:

すべてのコメントを見る
記事メニュー
ウィキ募集バナー