すべてのEFモデルのすべてのプロパティをループ/反映して列タイプを設定する

asp.net-core entity-framework entity-framework-core

質問

私のクライアントには、小数点(13,4)の指定でSQL Server小数点を格納する標準があります。その結果、非常に大きく、まだ成長しているスキーマでは、私は次のような約100のステートメントを持っています。

builder.Entity<MyObject>()
    .Property(x => x.MyField1)
    .ForSqlServerHasColumnType("decimal(13,4)");
builder.Entity<MyObject>()
    .Property(x => x.MyField2)
    .ForSqlServerHasColumnType("decimal(13,4)");
builder.Entity<MyObject2>()
    .Property(x => x.MyField1)
    .ForSqlServerHasColumnType("decimal(13,4)");

すべての小数点はデフォルトで小数点以下(13,4)にする必要があることをEFに直接伝えることができる機能がある場合は、それを使用したいと思います。そうでない場合は、モデル内のすべてのオブジェクト/プロパティをループするためにリフレクションを使用することができますので、これをいくつかのステートメントで実行できますか?

何かのようなもの:

foreach(var efObj in EntityFrameWorkObjects)
{
    foreach (var objProperty in efObj)
    {
        if (objProperty is decimal || objProperty is decimal?)
        {
            builder.Entity<efObj>()
                .Property(x => x.efObj)
                .ForSqlServerHasColumnType("decimal(13,4)");
        }
    }
}

オブジェクトが名前と説明を持つ場合、名前は必須であり、256文字に制限されているので、私はいくつかの他の規則を実装することができます。

更新:私はIvanのコメントのリンクをたどり、これに適応しました。

foreach (var p in builder.Model
    .GetEntityTypes()
    .SelectMany(t => t.GetProperties())
    .Where(p => 
        p.ClrType == typeof(decimal) ||
        p.ClrType == typeof(decimal?)))
{
    p.SqlServer().ColumnType = "decimal(13,4)";
}

すぐ後に、彼は完全な答えを出しました。これを10進数とヌル値の両方の10進数で少しずつ変更しました。

foreach (var pb in builder.Model
    .GetEntityTypes()
    .SelectMany(t => t.GetProperties())
    .Where(p => 
        p.ClrType == typeof(decimal) ||
        p.ClrType == typeof(decimal?))
    .Select(p => 
        builder.Entity(p.DeclaringEntityType.ClrType)
            .Property(p.Name)))
{
    pb.ForSqlServerHasColumnType("decimal(13,4)");
}

両方のアプローチが機能します!

Update 2:私は、上記のためにDbSet <>としてオブジェクトを宣言しなければなりませんでした。これは、行ごとにプロパティを設定しているときには必要ではないようです。

受け入れられた回答

EF Core v1.1.0では、このようなものを使うことができます。

foreach (var pb in modelBuilder.Model
    .GetEntityTypes()
    .SelectMany(t => t.GetProperties())
    .Where(p => p.ClrType == typeof(decimal) || p.ClrType == typeof(decimal?))
    .Select(p => modelBuilder.Entity(p.DeclaringEntityType.ClrType).Property(p.Name)))
{
    pb.ForSqlServerHasColumnType("decimal(13,4)");
}

更新: EF Core 2.0以降、モデルはデータベースプロバイダごとに個別に構築されるため、 HasAbcXyzメソッドは一般的なHasXyz置き換えられHasXyz 。更新されたコード(明示的に設定されたプロパティもスキップします)は次のようになります。

foreach (var property in modelBuilder.Model.GetEntityTypes()
    .SelectMany(t => t.GetProperties())
    .Where(p => p.ClrType == typeof(decimal) || p.ClrType == typeof(decimal?)))
{
    if (property.Relational().ColumnType == null)
        property.Relational().ColumnType = "decimal(13,4)";
}


Related

ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ