में संपत्ति संदर्भों के साथ आदिम पैरामीटर को प्रतिस्थापित करने के लिए एक LINQ अभिव्यक्ति विजिटर का उपयोग करना, मैं अपने सिस्टम के एक हिस्से के लिए एक डेटा परत लिखने की प्रक्रिया में हूं जो हर रोज चलने वाली स्वचालित नौकरियों के बारे में जानकारी लॉग करता है - नौकरी का नाम , यह कितना समय चल रहा था, परिणाम क्या था, आदिलैम्बडा अभिव्यक्ति
मैं इकाई फ्रेमवर्क का उपयोग कर डेटाबेस से बात कर रहा हूं, लेकिन मैं उन विवरणों को उच्च स्तरीय मॉड्यूल से छिपाने की कोशिश कर रहा हूं और मैं नहीं चाहता इकाई खुद को उजागर करने के लिए वस्तुओं।
हालांकि, मैं अपने इंटरफेस को नौकरी की जानकारी देखने के लिए उपयोग किए जाने वाले मानदंडों में बहुत लचीला बनाना चाहता हूं। उदाहरण के लिए, उपयोगकर्ता इंटरफ़ेस को उपयोगकर्ता को जटिल प्रश्नों को निष्पादित करने की अनुमति देनी चाहिए जैसे "मुझे सभी नौकरियां 'हैलो' दें जो 10:00 बजे से 11:00 बजे के बीच चलती थीं।" जाहिर है, यह गतिशील रूप से निर्मित Expression
पेड़ों के लिए नौकरी की तरह दिखता है।
तो मैं अपने डेटा परत (भंडार) और प्रकार Expression<Func<string, DateTime, ResultCode, long, bool>>
(लैम्ब्डा अभिव्यक्ति) के LINQ एक्सप्रेशन स्वीकार किया जाता है ऐसा करने में सक्षम होना चाहते हैं क्या तो पीछे के दृश्य परिवर्तित कि एक अभिव्यक्ति के लिए लैम्ब्डा कि मेरी इकाई की रूपरेखा ObjectContext
उपयोग कर सकते हैं एक Where()
खंड के अंदर एक फिल्टर के रूप में।
संक्षेप में, मैं Expression<Func<svc_JobAudit, bool>>
, जहां svc_JobAudit
इकाई की रूपरेखा डेटा वस्तु जो तालिका जहां काम के बारे में जानकारी संग्रहीत किया जाता है से मेल खाती है है के प्रकार Expression<Func<string, DateTime, ResultCode, long, bool>>
की एक लैम्ब्डा अभिव्यक्ति कन्वर्ट करने के लिए कोशिश कर रहा हूँ। (पहले प्रतिनिधि में चार पैरामीटर नौकरी के नाम से मेल खाते हैं, परिणामस्वरूप, और क्रमशः एमएस में कितना समय लगेगा)
मैं ExpressionVisitor
कक्षा का उपयोग करके बहुत अच्छी प्रगति कर रहा था जब तक कि मैं हिट नहीं करता
जब 'VisitLambda' से कहा जाता है, प्रकार 'System.Linq.Expressions.ParameterExpression' का एक नोड को फिर से लिखने की एक गैर-शून्य मान लौटाना चाहिए: एक ईंट की दीवार और इस त्रुटि संदेश के साथ एक
InvalidOperationException
प्राप्त इसी प्रकार का। वैकल्पिक रूप से, 'VisitLambda' को ओवरराइड करें और इसे इस प्रकार के बच्चों से न देखने के लिए बदलें।
मैं पूरी तरह से परेशान हूं। क्यों बिल्ली यह अभिव्यक्ति नोड्स को परिवर्तित करने की अनुमति नहीं देगा जो संदर्भ गुणों को संदर्भित करता है जो नोड्स को संदर्भित करता है? क्या इस बारे में जाने का कोई और तरीका है?
यहां कुछ नमूना कोड है:
namespace ExpressionTest
{
class Program
{
static void Main(string[] args)
{
Expression<Func<string, DateTime, ResultCode, long, bool>> expression = (myString, myDateTime, myResultCode, myTimeSpan) => myResultCode == ResultCode.Failed && myString == "hello";
var result = ConvertExpression(expression);
}
private static Expression<Func<svc_JobAudit, bool>> ConvertExpression(Expression<Func<string, DateTime, ResultCode, long, bool>> expression)
{
var newExpression = Expression.Lambda<Func<svc_JobAudit, bool>>(new ReplaceVisitor().Modify(expression), Expression.Parameter(typeof(svc_JobAudit)));
return newExpression;
}
}
class ReplaceVisitor : ExpressionVisitor
{
public Expression Modify(Expression expression)
{
return Visit(expression);
}
protected override Expression VisitParameter(ParameterExpression node)
{
if (node.Type == typeof(string))
{
return Expression.Property(Expression.Parameter(typeof(svc_JobAudit)), "JobName");
}
return node;
}
}
}
[लैम्ब्डा अभिव्यक्ति में पैरामीटर बदलें] (http://stackoverflow.com/questions/11159697/replace-parameter-in-lambda-expression) –