2012-03-08 12 views
11

कैसे संपत्ति अभिव्यक्ति जो StructuralTypeConfiguration<TStructuralType>.Ignore<TProperty>(Expression<Func<TStructuralType, TProperty>> propertyExpression) विधि आह्वान करने के लिए इस्तेमाल किया जा सकता करने के लिए PropertyInfo कन्वर्ट करने के लिए?कैसे संपत्ति अभिव्यक्ति को 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:

मैं के संबंध में यह कर रहा हूं।

अद्यतन

कोड जो काम नहीं कर रहा:

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

आपको अपना कोड दिखाना चाहिए जो काम नहीं कर रहा है ... –

+0

@ जोनस्केट - जोड़ा गया। – 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: System.RuntimeType.SanityCheckGenericArguments पर (RuntimeType [] genericArguments, RuntimeType [] genericParamters) System.Reflection.RuntimeMethodInfo.MakeGenericMethod पर Here_is_this_code (DbModelBuilder modelBuilder) – Pol

+1

में (टाइप [] methodInstantiation) जब मैं 'टिप्पणी की .MakeGenericMethod (...) 'मुझे मिला है' देर से बाध्य संचालन प्रकार या विधियों पर नहीं किया जा सकता है जिसके लिए जेनरिक पैरामीटर सत्य हैं। ' – Pol

+0

वर्तमान संस्करण का प्रयास करें –

1

TProperty केवल सी # स्रोत कोड पाठ में मौजूद है। संकलक हमेशा इसे एक ठोस प्रकार के लिए हल करता है। यदि आप एक विधि

void Test<T>(T arg) 
{ 
} 

है और यह इस

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

की तरह कॉल करते हैं संकलक दो तरीकों के लिए कोड उत्पन्न करता है!

void Test(string arg) 
{ 
} 

void Test(int arg) 
{ 
} 

इसका मतलब है आप अपने सामान्य मापदंडों के लिए ठोस प्रकार की आपूर्ति करने के लिए है कि अगर आप एक invokable विधि करना चाहते हैं।

2

संपत्ति भाव संपत्ति पहुँच की आवश्यकता एक विशिष्ट वस्तु पर किया जाना है। यहां कुछ विकल्प हैं जिन्हें आप यहां ले सकते हैं। सबसे पहले, अगर यह आपके इकाई वस्तुओं में से एक के भीतर किया जा रहा है, आप सरल उपयोग एक ConstantExpression संपत्ति अभिव्यक्ति का निर्माण करने के कर सकते हैं:

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

हालांकि, बाद से आप एक Expression<Func<TStructuralType, TProperty>> की जरूरत है, तो ऐसा लगता है जैसे आप करने जा रहे हैं एक ParameterExpression का उपयोग कर इसे बनाने के लिए है:

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

हालांकि, यहां किकर है ... यह सिर्फ एक MemberExpression है। अभिव्यक्ति आप की जरूरत में बदलने के लिए, आपको Expression.Lambda उपयोग करने के लिए आप किस प्रकार की जरूरत है की एक समारोह <> अभिव्यक्ति प्राप्त करने की आवश्यकता। समस्या? आप लैम्ब्डा अभिव्यक्ति के सामान्य मानकों को परिभाषित करने के लिए संपत्ति के प्रकार को नहीं जानते!

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

यह इस तरह से करने की समस्या का क्रूक्स है। ऐसा नहीं है कि यह नहीं किया जा सकता है ... यह सिर्फ इस विधि का उपयोग करने के लिए काम नहीं करेगा। आप थोड़ा क्रम और स्थिर टाइपिंग प्रवंचना (और साथ ही Funcs के बजाय कार्रवाई का विवेकपूर्ण उपयोग) का उपयोग करने के लिए इस सही ढंग से काम करने के लिए होगा।