2010-05-10 9 views
5

क्या एंटीटी फ्रेमवर्क/System.Data.Entity.dll पर निर्भरता पेश किए बिना EdmFunctionAttribute का लाभ उठाने का कोई अच्छा तरीका है?एंटिटी फ्रेमवर्क निर्भरता/कार्यान्वयन विवरण को उजागर किए बिना EdmFunctionAttribute का उपयोग करें?

मैंने सोचा कि मेरे पास एक विधि और एक ठोस कार्यान्वयन के साथ एक इंटरफ़ेस हो सकता है जो इसे डेटाबेस फ़ंक्शन पर मैप करने के लिए EdmFunctionAttribute का उपयोग करके विधि लागू करता है।

मेरे पास एक असेंबली में एक संदर्भ इंटरफेस IMyContext एक असेंबली और एक इकाई फ्रेमवर्क कार्यान्वयन MyContext में परिभाषित किया गया है।

public interface IMyContext 
{ 
    double SomeFunction(double first, double second); 

    // other interface details here 
} 

public partial class MyContext : IMyContext 
{ 
    [EdmFunction("MyNamespace", "MyDatabaseFunction")] 
    public double SomeFunction(double first, double second) 
    { 
     throw new NotSupportedException("This method may only be called as part of a LINQ expression."); 
    } 

    // rest of interface implementation here 
} 

मैं एक कारखाने (पर्दे के पीछे StructureMap का उपयोग) का उपयोग इंटरफ़ेस प्रकार के रूप में एक संदर्भ उदाहरण पाने के लिए:

using (IMyContext context = ContextFactory.GetNewContext()) 
{ 
    var results = context.Table.Select(t => context.SomeFunction(t.Col1, t.Col2)).ToList(); 
} 

यह एक NotSupportException कह रही है कि LINQ संस्थाओं के लिए विधि 'को नहीं पहचानता है फेंकता डबल कुछ समारोह (डबल, डबल) '।

अगर मैं

using (MyContext context = ContextFactory.GetNewContext() as MyContext) 
{ 
    ... 
} 

तो ठोस कार्यान्वयन के लिए संदर्भ डाली यह काम करता है, लेकिन फिर मैं ठोस कार्यान्वयन, जो मैं नहीं करना चाहते हैं निर्दिष्ट करने के लिए आवश्यक कर रहा हूँ।

फ़ंक्शन को संदर्भ वर्ग का सदस्य नहीं होना चाहिए, मैंने इसे एक्सप्लोर करने के लिए वहां रखा है।

+0

मुझे एक ही स्थिति का सामना करना पड़ रहा है। मैं भी उम्मीद कर रहा था कि इंटरफ़ेस संदर्भ के माध्यम से एक्सेस किए जाने पर EdmFunctionAttribute को हल किया जाएगा, लेकिन इसका कोई फायदा नहीं हुआ। कई संदर्भों (एकाधिक डेटाबेस) के साथ काम करते समय यह और भी मुश्किल हो जाता है। – kdawg

+0

इसके लायक होने के लिए, मैं इस मुद्दे को हल नहीं कर सका और मुझे अपने रिपोजिटरी (आपके मामले में संदर्भ) के ठोस कार्यान्वयन पर डीबी फ़ंक्शन को थप्पड़ मारना पड़ा, जिसका अर्थ है कि सभी फ़ंक्शन कॉल मेरे रिपोजिटरी कक्षा में रहनी चाहिए - यानी: मेरा क्लाइंट कोड सीधे इसका उपयोग नहीं कर सका। मैं इसके साथ रोमांचित नहीं हूं, लेकिन यह काम करता है (और यह रिपोजिटरी के भीतर रहने के लिए कोड पूछताछ करता है, जो कुछ तर्क देंगे कि यह कहां से संबंधित है)। – kdawg

उत्तर

1

आप Generic Repository Pattern का उपयोग करें और वहाँ एक विधि के रूप IQueryable inteface का पर्दाफाश, की तरह नहीं कर सकते:

IQueryable FindAll(Func<T,bool> exp); 
0

यह संभव के रूप में LINQ क्वेरी बिल्डर इंटरफ़ेस प्रकार और नहीं ठोस वर्ग की जांच करेंगे नहीं है। अभिव्यक्ति वृक्ष में इंटरफ़ेस की विधि का विधि संदर्भ होगा और जब आप विधि पर विशेषताओं की जांच करेंगे, तो यह किसी भी विशेषता को वापस नहीं करेगा।

आप एक अभिव्यक्ति विज़िटर बना सकते हैं और अपने अभिव्यक्ति के पेड़ पर जा सकते हैं और प्रकार को इंटरफ़ेस से ठोस प्रकार में बदल सकते हैं।

TypeReplacer tr = new TypeReplacer(); 
tr.Visit(ex); 

class TypeReplacer: ExpressionVisitor{ 
    protected override MethodCallExpression MethodCall(MethodCallExpression exp) 
    { 
     // compare exp.Method and 
     // replace it with concrete Type's method 
     return exp; 
    } 
} 
+0

क्षमा करें, आपका उत्तर कुछ भी हल नहीं करता है जो पहले से ही प्रश्न में लागू नहीं किया गया था। आपके समाधान को अभी भी संदर्भ इंटरफ़ेस के बजाय ठोस संदर्भ वर्ग के संदर्भ की आवश्यकता है। – GWB

+0

मैंने अपना जवाब अपडेट कर दिया है। –

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