migrationのテーブル名や列名をLowerSnakeCaseに設定する

EF Coreを利用してCodeFirstでMigrationによりデータベースのテーブルを作成するときですが、テーブル名と列名がC#のプロパティ名となるため、デフォルトではUpperCamelCaseになります。

これを変更するにはテーブル名であれば{Table("table_name")、列名であれば[Column("column_name")]とそれぞれに設定することで対応可能です。

しかし、このようにアノテーションを設定することは結構面倒です。特にPostgreSQLを使用している場合には列名に大文字を使用するとハマりどころとなったりします。

お手軽に列名をLowerSnakeCaseに変換する

少し調べてみたところ、EF CoreのIssueに以下のようにContextクラスのOnModelCreatingで列名とテーブル名を変換する方法が紹介されていましたので試してみました。

namespace Some.Models
{
    public class SomeContext:DbContext
    {
        public DbSet<...

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            ...
            base.OnModelCreating(modelBuilder);

            FixSnakeCaseNames(modelBuilder);
        }

        private static void FixSnakeCaseNames(ModelBuilder modelBuilder)
        {
            var mapper = new Npgsql.NpgsqlSnakeCaseNameTranslator();

            foreach (var entity in modelBuilder.Model.GetEntityTypes())
            {
                // modify column names
                foreach (var property in entity.GetProperties())
                {
                    property.Relational().ColumnName = mapper.TranslateMemberName(property.Relational().ColumnName);
                }

                // modify table name
                entity.Relational().TableName = mapper.TranslateMemberName(entity.Relational().TableName);

                // move asp_net tables into schema 'identity'
                if (entity.Relational().TableName.StartsWith("asp_net_"))
                {
                    entity.Relational().TableName = entity.Relational().TableName.Replace("asp_net_", string.Empty);
                    entity.Relational().Schema = "identity";
                }
            }
        }
    }
}

結果としてはこれで問題なくテーブル名と列名がLowerSnaleCaseになりましたので感謝感謝です。

参考

pluggable schemes for mapping c# names · Issue #5159 · aspnet/EntityFrameworkCore

このところPostgreSQLへC#から接続することを色々と試しているせいでしょうが、Shay Rojanskyさんには本当にお世話になっています。大抵の問題について回答されていてShay Rojanskyの回答からいろいろな人がいろいろな方法を紹介されている事が多いのでとても感謝しています。

C#実践開発手法 (マイクロソフト公式解説書)

C#実践開発手法 (マイクロソフト公式解説書)

異なるプロジェクトにあるContextでMigrationを実行する

複数のプロジェクトで構成されたソリューションのうち、Startupプロジェクト以外でef migrationsを実行する場合には以下のようにDbContextを含むプロジェクトでマイグレーションコマンドを実行する必要があります。

SampleSln
  -- StartupProject
  -- RepositoryProject
       -- SomeDbContext

仮に上記のようなプロジェクト構成となっている場合には、以下の通りコマンドを実行します。 (RepositoryProjectのSomeDbContextが参照する接続先はStartupProjectに定義されていることとします。)

$ cd RepositoryProject

# Migrationファイルを作成する
$ dotnet ef migrations add AddHogeTable --context SomeDbContext -v --startup-project ../StartupProject

# Migrationをデータベースへ反映する
$ dotnet ef database update AddHogeTable --context SomeDbContext -v --startup-project ../StartupProject

参考

Migration in different assembly than target assembly not supported · Issue #5900 · aspnet/EntityFrameworkCore

C# 7.0 Pocket Reference: Instant Help for C# 7.0 Programmers

C# 7.0 Pocket Reference: Instant Help for C# 7.0 Programmers

Resharperを利用時にCleanup Code実行時にif文で中括弧が削除される

Resharperの2017.2を利用していると、CleanupCodeを実行時にif文の中括弧が削除されるフォーマットが実行されることがあります。

具体的にはこのような感じになります。

CleanupCode実行前のコード

if( condition == true)
{
    Console.Writeline("test");
}

Cleanup Code実行後のコード

if( condition == true)
    Console.Writeline("test");

中括弧の有無についての是非はそれぞれあると思うのですが、個人的には必ず中括弧はつけるためこの設定は見直したいと思いました。

対応方法

Cleanup Codeの実行時の設定を変更するには、Code Cleanupの設定をコピーしてAdd/Remove barances for...のチェックを外せば中括弧が削除されることはなくなります。

image.png (165.8 kB)

これで中括弧が削除されることはなくなりました。

Resharper

JetBrains ReSharper Ultimate 2017.2.2  Build 109.0.20171006.122324
dotCover 2017.2.20171006.131113
dotTrace 2017.2.20171006.131127
ReSharper 2017.2.20171006.123800
dotMemory 2017.2.20171006.131009

参考

c# - ReSharper - force curly braces around single line - Stack Overflow