2012-03-08 8 views
11

PropertyInfoStructuralTypeConfiguration<TStructuralType>.Ignore<TProperty>(Expression<Func<TStructuralType, TProperty>> propertyExpression)メソッドを呼び出すために使用できるプロパティ式に変換する方法はありますか?PropertyInfoをプロパティ式に変換して汎用メソッドを呼び出す方法

私は表現を構築するためにExpression.Property()を使用しようとしましたが、私はpropertyExpressionパラメータとしてこの表現を使用する場合、私は、次のエラーを取得しています:

The type arguments for method cannot be inferred from the usage. Try specifying the type arguments explicitly.

このエラーはおそらく、私は知らないTProperty型パラメータを参照PropertyInfoのみを指定する方法。

私はこれに関して:Use Entity Framework's StructuralTypeConfiguration.Ignore() to Ignore all properties but specified setとしています。動作していない

UPDATE

コード:

+1

コードが正常に動作していないことを示す必要があります。 –

+0

@JonSkeet - 追加されました。 – Pol

答えて

19
var entityType = propertyInfo.DeclaringType; 
var parameter = Expression.Parameter(entityType, "entity"); 
var property = Expression.Property(parameter, propertyInfo); 
var funcType = typeof(Func<,>).MakeGenericType(entityType, propertyInfo.PropertyType); 
var lambda = Expression.Lambda(funcType, property, parameter); 

structureConfiguration.GetType() 
    .GetMethod("Ignore") 
    .MakeGenericMethod(propertyInfo.PropertyType) 
    .Invoke(structureConfiguration, new[]{lambda}); 
+0

しようとしましたが、タイプまたはメソッドに1つの汎用パラメータがありますが、2つの汎用引数が提供されています。ジェネリック引数はそれぞれのジェネリックパラメータごとに指定する必要があります。StackTrace:私は '.MakeGenericMethod(コメント場合System.Reflection.RuntimeMethodInfo.MakeGenericMethodでSystem.RuntimeType.SanityCheckGenericArgumentsで (RuntimeType [] genericArguments、RuntimeType [] genericParamters) はHere_is_this_code(DbModelBuilder ModelBuilderの) – Pol

+1

で([] methodInstantiationを入力します) ...) '私は' ContainsGenericParametersが真である型やメソッドでは、レイトバウンド操作を実行できません。 ' – Pol

+0

現在の変更を試す –

1
 var propertyInfo = typeof(Foo).GetProperties()[0]; 
     var expression = Expression.Default(typeof(Foo)); 
     var expressionProperty = Expression.Property(expression, propertyInfo); 
     Ignore(expressionProperty); 

TPropertyのみのC#ソースコードのテキストに存在します。コンパイラは常にそれを具体的な型に解決します。あなたはこの方法

void Test<T>(T arg) 
{ 
} 

を持っていると、コンパイラは二つの方法のためのコードを生成し、この

Test("hello"); 
Test(3); 

のようにそれを呼び出すと!

void Test(string arg) 
{ 
} 

void Test(int arg) 
{ 
} 

これは、呼び出し可能なメソッドを使用する場合は、汎用パラメータに具体的な型を指定する必要があることを意味します。

2

プロパティ式では、プロパティアクセスが特定のオブジェクトに存在する必要があります。ここにはいくつかのオプションがあります。あなたがExpression<Func<TStructuralType, TProperty>>を必要とするので、あなたがしようとしているように思える、しかし

// Already have PropertyInfo in propInfo 
Expression.Property(Expression.Constant(this, this.GetType()), propInfo) 

:これはあなたのエンティティオブジェクトの1つに行われている場合、最初に、あなたは簡単な使用ConstantExpressionは、プロパティ式を構築することができますParameterExpressionを使用して構築する必要があります。

ParameterExpression pe = Parameter.Expression(typeof(MyEntity), "eParam"); 
Expression propExp = Expression.Property(pe, propInfo); 

ここではキッカーです...これは単なるMemberExpressionです。必要な式に変換するには、Expression.Lambdaを使用して、必要な型のFunc <>式を取得する必要があります。問題?ラムダ式のジェネリックパラメータを定義するプロパティの型がわからない!

Expression<Func<MyEntity, ????>> eFunc = Expression.Lambda<Func<MyEntity, ????>>(propExp, pe); 

これは、このようにすることの重要なポイントです。そうすることができないと言っているわけではありません...この方法でこの方法を使うのは、うまくいかないことです。これを正しく動作させるには、ビットランタイムと静的な入力トリッキーを使用する必要があります(また、Funcの代わりにアクションを慎重に使用する必要があります)。

関連する問題