2016-10-17 8 views
6

पर पूरी तरह से पुनर्लेखन करने के लिए कैसे करें क्योंकि मैं पहले से कहीं अधिक समझता हूं।ओडीएटी क्वेरी स्ट्रिंग को .NET अभिव्यक्ति वृक्ष

मैं ओडीटा क्वेरी स्ट्रिंग के रूपांतरण को सीधे .NET अभिव्यक्ति वृक्ष में बदलने का प्रयास कर रहा हूं। इस पर कई प्रश्न और आलेख दिखाई देते हैं, लेकिन कोई जवाब नहीं है जो Microsoft.Data.OData नेमस्पेस पर निर्भर करता है (यानी, सभी उदाहरण वेबएपीआई, इकाई फ्रेमवर्क या किसी अन्य लाइब्रेरी पर भरोसा करते हैं)।

जवाब यह है कि एक सार समाधान प्रदान में सबसे अच्छा है यहाँ है:

https://stackoverflow.com/a/21536369/701346

इन दो पंक्तियों को मिला मुझे शुरू कर दिया:

IEdmModel model = EdmxReader.Parse(new XmlTextReader(/*stream of your $metadata file*/)); 
IEdmEntityType type = model.FindType("organisation"); 

ज्यादा परिश्रम के बाद, मैंने सीखा है कि ओडाटा को अपने मालिकाना अभिव्यक्ति वृक्ष मॉडल उत्पन्न करने के लिए एक ईडीएम की आवश्यकता होती है। यह केवल एक मॉडल है। अंततः अपने स्वयं के अभिव्यक्ति वृक्ष उत्पन्न करने के लिए आपको उस मॉडल को पार करना होगा।

तो मैंने यह सब किया है (तरह)। मैं इस लेख जो मुझे पता चला किसी भी नेविगेशन के बिना एक बुनियादी ईडीएम बनाने का तरीका पर हुआ:

https://blogs.msdn.microsoft.com/alexj/2012/12/06/parsing-filter-and-orderby-using-the-odatauriparser/

कि का उपयोग करना, मैं एक EDM जनरेटर कि रिकर्सिवली एक वर्ग ईडीएम निर्माण करने के लिए के माध्यम से दर्शाता बना दी। समस्या यह है कि यह हास्यास्पद रूप से जटिल है और गतिशील रूप से ईडीएम बनाने के तरीके के बारे में ऑनलाइन अधिक जानकारी नहीं है, इसलिए यह किसी भी नेविगेशन गुणों को परिभाषित नहीं करता है और केवल एक इकाई के साथ काम करता है।

मैंने फिर एक ओडाटाएक्सप्रेसियन विज़िटर बनाया जो System.Linq.Expressions.ExpressionVisitor के बाद मॉडलिंग किया गया है। यह बहुत अच्छा काम करता है। ,

(
    $CustomerLocation.Name == "Oxford Mall" || 
    $CustomerLocation.Street == "123 whatever ln" 
) && 
$CustomerLocation.Id == 2 

यह काम करता है, भी क्योंकि मैं इसे एक delagate के संकलन और यह और इसे में एक CustomerLocation वस्तु पारित कर सकते हैं:

var filter = ODataUriParser.ParseFilter(
    "(Name eq 'Oxford Mall' or Street eq '123 whatever ln') and Id eq 2", 
    edmBuilder.Model, edmBuilder.Model.FindType(typeof(CustomerLocation).FullName)); 

इस अभिव्यक्ति और उत्पन्न: यह इस OData क्वेरी स्ट्रिंग लेने में सक्षम है सही सच/झूठी वापस कर देगा। मैंने अभी तक ईएफ 6 या मेरे अन्य अभिव्यक्ति-आधारित ढांचे के साथ इसका परीक्षण नहीं किया है, हालांकि।

हालांकि, मुझे लगता है कि मैं यहां एक पहिया का पुनर्निर्माण कर रहा हूं। 1 के लिए मौजूदा साधन होना चाहिए) अकेले कक्षा से एक सम्मेलन-आधारित ईडीएम उत्पन्न करना और 2) परिणामी ओडाटा अभिव्यक्ति वृक्ष को .NET अभिव्यक्ति वृक्ष में परिवर्तित करना।

+1

निम्न लिंक देखें। यह विभिन्न भाषाओं में आधिकारिक ओडाटा पुस्तकालयों की सूची है। शायद एक पुस्तकालय है जो आपकी आवश्यकताओं का समर्थन करता है। http://www.odata.org/libraries/ – Charles

+0

@ चार्ल्स यह एक अच्छा लिंक है। मैं http://odata.github.io/odata.net/ पढ़ रहा हूं और यह एक बड़ी मदद है। एक बार मैं इसे खत्म करने के बाद एक अद्यतन पोस्ट करूंगा। – oscilatingcretin

+0

मैं कुछ इसी तरह की तलाश में हूं - क्या आपने यह काम करने के लिए प्रबंधन किया था? कुछ समान परियोजनाएं हैं ("लिंक टू क्वेरीस्ट्रिंग" और "लिंक 2 रीस्ट" लेकिन वे केवल एक ओडीटा क्वेरी को एक गणना करने के लिए लागू करते हैं, वैध अभिव्यक्ति वृक्ष नहीं बनाते हैं। – mcintyre321

उत्तर

1

मैं टोपी एक ही मुद्दा कुछ समय पहले और निम्नलिखित दृष्टिकोण के साथ इसे हल:

  1. एक OData क्वेरी स्ट्रिंग है, जो एक URI से यह निर्माण करके प्राप्त किया जा सकता से ODataQueryOptions बनाएँ (मैं और अधिक में यह वर्णित Modifying ODataQueryOptions on the fly
  2. में कोड उदाहरण के साथ विस्तार से एक Expression (वास्तव में एक MethodCallExpression) को ODataQueryOptionsFilterQueryOption तरह के विभिन्न भागों में परिवर्तित करने के लिए हम एक खाली IQueryable साथ संयोजन के रूप में उपयोग कर सकते हैं ApplyTo (परिवर्तित ०१२३२५४५२३काफी इस के समान) है:

    public static Expression ToExpression<T>(this FilterQueryOption filterQueryOption) 
    where T: class 
    { 
        IQueryable queryable = Enumerable.Empty<T>().AsQueryable(); 
        queryable = filterQueryOption.ApplyTo(queryable, new OdataQuerySettings()); 
    
        return queryable.Expression; 
    } 
    
  3. $skip परिवर्तित और $topSkip() और Take() का उपयोग कर के रूप में के रूप में आसान है।

  4. परिदृश्य के आधार पर, इस अभिव्यक्ति को लैम्ब्डा के रूप में प्रयोग करने योग्य बनाने के लिए हमें ExpressionVisitor का उपयोग करना पड़ सकता है जो MethodCallExpression के तर्क को प्रतिस्थापित करता है।
  5. एक लैम्ब्डा बनाना तो Body और Parameter और बनाने के लिए एक नया Expression.Lambda लेने का केवल एक मामला है:

    var expressionLambda = Expression.Lambda<Func<T, bool>> 
        (
         visitedMethodCallExpression.Body, 
         Expression.Parameter(typeof(T), "$it") 
        ); 
    

अधिक पूर्ण उदाहरण Converting ODataQueryOptions into LINQ Expressions in C# देखें (लेकिन यह अंत में EntityFramework का उपयोग करता है , तो आप बाकी को छोड़ना चाहेंगे)।

संबंधित मुद्दे