豚吐露@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
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
e.g.) DbContext
- public class HogedbContext : DbContext
- {
- public DbSet<Report> report { get; set; }
-
- public string schema { get; set; }
-
- public HogedbContext(string schemaName = "dbschema")
- {
- this.schema = schemaName;
- }
-
- protected override void OnModelCreating(DbModelBuilder modelBuilder)
- {
- base.OnModelCreating(modelBuilder);
- }
- }
3行目は、DbSetなので置いといて。
5行目は、schema名持っとくメンバを作っといた。コンストラクタでschema名指定されたら、そいつ使うようにしてる。
12行目、今回のキモ。OnModelCreating()をoverrideして、自分で作ったConventionクラスを与えてやる。
14行目、実際にConventionを与えているところ。HogedbConventionが自分で作ったConventionクラス。
5行目は、schema名持っとくメンバを作っといた。コンストラクタでschema名指定されたら、そいつ使うようにしてる。
12行目、今回のキモ。OnModelCreating()をoverrideして、自分で作ったConventionクラスを与えてやる。
14行目、実際にConventionを与えているところ。HogedbConventionが自分で作ったConventionクラス。
見慣れないこいつは、DbContextにDB接続時の条件を色々与えてやれるクラス。
Conventionなので慣例って意味ですね。DbContextに慣例を与えてやるんです。
e.g.) Convention
Conventionなので慣例って意味ですね。DbContextに慣例を与えてやるんです。
e.g.) Convention
- class HogedbConvention : Convention
- {
- public HogedbConvention(string schema)
- {
- this.Types().Configure(c => c.ToTable(pascal2snake(c.ClrType.Name), schema));
-
- this.Properties().Configure(p => p.HasColumnName(p.ClrPropertyInfo.Name.ToLower()));
- }
-
- static private string pascal2snake(string src)
- {
- string pattern = "([^_])([A-Z])";
- string replacement = "$1_$2";
-
- return Regex.Replace(Regex.Replace(src, pattern, replacement), pattern, replacement).ToLower();
- }
- }
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回『アンダーバー以外+大文字を見つけたら大文字の前にアンダーバーを入れる』って正規表現をやってる。
で、正規表現で処理した後、全部小文字化してる。
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秒