1

リフレクションを使用して OnModelCreating の DbModelBuilder オブジェクトを自動化しようとしています。

基本クラスから継承するクラスがいくつかあります: Enumeration データベースでは、これらのテーブルの Id を設定できるようにしたいので、OnModelCreating で呼び出します

modelBuilder.Entity<SomeClass>()
            .Property(sc => sc.SomeClassId)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);

モデルをデータベースに適用するときにこれを忘れると、削除してやり直す必要があるため、リフレクションを使用してこれを自動化したいと思います。

クラス モデルに属性を設定できることはわかっていますが、そこには配置したくありません。

ここにコード。ジェネリック メソッドを呼び出そうとすると、何らかの理由で失敗します。誰か提案はありますか?

//Get all of my Models / Tables that I want to be able to specify a proimary key for.

var enumerationPropertyInfos = thisDbContext
    .GetType()
    .GetProperties();
    .Where(p => p.PropertyType.IsGenericType
        && p.PropertyType.GetGenericTypeDefinition() == typeof(DbSet<>)
        && p.PropertyType.GetGenericArguments().First().BaseType == typeof(MyEnumerationBase));


foreach (PropertyInfo pi in enumerationPropertyInfos)
{
    //modelBuilder.Entity<SomeClass>()
    var config = modelBuilder.GetType()
        .GetMethod("Entity")
        .MakeGenericMethod(pi.PropertyType)
        .Invoke(modelBuilder, null);

    //Prepare .Property(...)
    var property = config.GetType().GetMethods().Where(m => m.Name == "Property").First();

    var propertyExpression = typeof(Expression<>)
        .MakeGenericType(typeof(Func<,>)
        .MakeGenericType(pi.PropertyType, typeof(int)));

    //Prepare e => e.SomeClassId
    var paramEx = Expression.Parameter(pi.PropertyType.GetGenericArguments().First(), "e");
    var lambdaEx = Expression.Lambda(Expression.Property(paramEx, pi.PropertyType.GetGenericArguments().First().Name + "Id"), paramEx);

    //Execute .Property(e => e.SomeClassId)
    PrimitivePropertyConfiguration propertyResult = (PrimitivePropertyConfiguration)property
        .MakeGenericMethod(typeof(Expression))
        .Invoke(config, new[] { lambdaEx });

    propertyResult.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
}
4

1 に答える 1