11

すべての DateTime と DateTime で Sql Server の「datetime2」タイプを使用する必要がありますか? すべてのエンティティ オブジェクトのプロパティ。これは通常、次のような流暢な API で行われます。

modelBuilder.Entity<Mail>().Property(c => c.SendTime).HasColumnType("datetime2");

ただし、すべてのエンティティ タイプのすべての DateTime フィールドに対して手動でこれを行うことは避けたいと思います。(DateTime プロパティは、それらが定義されているエンティティ タイプに固有であるため、すべての DateTime プロパティを配置できる共通の基本タイプはありません)。

短い質問: 私のオプションは何ですか?

長い質問: リフレクションの使用を検討していて、試みましたが、リフレクションを介して一般的な流暢な API メソッドを呼び出す必要があったため、流暢な API はこの種の作業にはあまり適していないようで、非常に面倒でした。これが私の厄介な試みです:

    protected override void OnModelCreating(DbModelBuilder modelBuilder) {
        var genericEntityMethod = modelBuilder.GetType().GetMethod("Entity");
        var entityTypes = Assembly.GetExecutingAssembly().GetTypes().Where(t => t.IsClass && !t.IsAbstract && t.GetInterface("IEntity") != null);
        foreach (var t in entityTypes) {
            var props = t.GetProperties().Where(p => 
                p.GetSetMethod() != null && 
                p.GetGetMethod() != null && 
                (p.PropertyType == typeof (DateTime) ||  
                p.PropertyType == typeof(DateTime?)));
            foreach (var propertyInfo in props) {
                var entityMethod = genericEntityMethod.MakeGenericMethod(t.GetType());
                var entityTypeConfiguration = entityMethod.Invoke(modelBuilder,null);
                var lambdaExpression = Expression.Lambda(Expression.MakeMemberAccess(Expression.Parameter(t), propertyInfo), Expression.Parameter(t));

                //var propertyMethod = entityTypeConfiguration.GetType().GetMethod("Property");  // Cant get this to work
                var propertyMethods = entityTypeConfiguration.GetType().GetMethods().Where(m => m.ReturnType == typeof(DateTimePropertyConfiguration)).ToList();
                var propertyMethod = propertyInfo.PropertyType == typeof (DateTime) ? propertyMethods[0] : propertyMethods[1];

               var dateTimePropertyConfiguration = propertyMethod.Invoke(entityTypeConfiguration, new object[] {lambdaExpression});
                var hasColumnTypeMethod = entityTypeConfiguration.GetType().GetMethod("HasColumnType");
                hasColumnTypeMethod.Invoke(dateTimePropertyConfiguration, new object[]{ "datetime2" });
            }
        }
        base.OnModelCreating(modelBuilder);
    }

これは次の行で失敗します。

                   var dateTimePropertyConfiguration = propertyMethod.Invoke(entityTypeConfiguration, new object[] {lambdaExpression});

このエラー (Entities.Order は、DateTime プロパティを持つエンティティ オブジェクトの 1 つです):

Object of type 'System.Linq.Expressions.Expression`1[System.Func`2[Entities.Order,System.Nullable`1[System.DateTime]]]' cannot be converted to type 'System.Linq.Expressions.Expression`1[System.Func`2[System.RuntimeType,System.Nullable`1[System.DateTime]]]

誰かがこのリフレクション アプローチで私を助けてくれますか?

4

1 に答える 1

4

はるかに優れたアプローチがあります。残念ながら、このアプローチは、EF6 で利用できるようになるカスタム規則に基づいています。EF6 Alpha 2を試して、自分でカスタム規則を試すことができます。ウォークスルーには、正確な要件の例が含まれています。

リフレクションに関する問題を解決するには、このブログ記事を確認してください。リフレクションを使用してマッピングを生成するためのコードについて説明します (関連するオープン ソース プロジェクトがあるはずです)。

于 2012-12-20T11:08:53.387 に答える