11

मैं अपने एमवीसी अनुप्रयोग में डेटा एक्सेस के लिए सर्वोत्तम पैटर्न पर निर्णय लेने की कोशिश कर रहा हूं। वर्तमान में, एमवीसी स्टोरफ्रंट श्रृंखला का पालन करने के बाद, मैं रिपॉजिटरीज़ का उपयोग कर रहा हूं, एक सेवा परत में IQueryable का खुलासा करता हूं, जो तब फ़िल्टर लागू करता है। प्रारंभ में मैं LINQtoSQL का उपयोग कर रहा हूं उदा। आईडी के लिएक्या रिपॉजिटरीज सेवा परत के लिए IQueryable का खुलासा करना चाहिए या कार्यान्वयन में फ़िल्टरिंग करना चाहिए?

public class LINQtoSQLRepository : IMyRepository 
{ 
    public IQueryable<MyClass> GetAll() 
    { 
     return from table in dbContext.table 
      select new MyClass 
      { 
       Field1 = table.field1, 
       ... etc. 
      } 
    } 
} 

फिल्टर::

public interface IMyRepository 
{ 
    IQueryable<MyClass> GetAll(); 
} 

में लागू

public static class TableFilters 
{  
    public static MyClass WithID(this IQueryable<MyClass> qry, string id) 
    { 
     return (from t in qry 
       where t.ID == id 
       select t).SingleOrDefault(); 
    }  
} 

सेवा से कहा जाता है:

public class TableService 
{ 
    public MyClass RecordsByID(string id) 
    { 
     return _repository.GetAll() 
         .WithID(id); 
    } 
} 

जब मैं लागू करने के साथ प्रयोग किया मैं कोई समस्या हुई थी Entity Framew का उपयोग कर भंडार LINQ से इकाइयों के साथ ओर्क। मेरे प्रोजेक्ट में फ़िल्टर क्लास में उपरोक्त उदाहरण में "WHERE ... == ..." से कुछ और जटिल परिचालन शामिल हैं, जो मुझे विश्वास है कि LINQ प्रदाता के आधार पर विभिन्न कार्यान्वयन की आवश्यकता है। विशेष रूप से मुझे एक एसक्यूएल "कहां ... IN ..." खंड करने की आवश्यकता है। मैं का उपयोग कर फिल्टर कक्षा में इस लागू करने में सक्षम हूँ:

string[] aParams = // array of IDs 
qry = qry.Where(t => aParams.Contains(t.ID)); 

हालांकि, ताकि इकाई की रूपरेखा के खिलाफ इस प्रदर्शन करने के लिए, मैं इस तरह के BuildContainsExpression जो इकाई की रूपरेखा से जुड़ा हुआ है के रूप में एक समाधान प्रदान करने के लिए की जरूरत है। इसका मतलब है कि अंतर्निहित प्रदाता के आधार पर, मुझे इस विशेष फ़िल्टर के 2 अलग-अलग कार्यान्वयन करना होगा।

मैं इस बारे में किसी भी सलाह की सराहना करता हूं कि मुझे यहां से कैसे आगे बढ़ना चाहिए। मुझे ऐसा लगता है कि मेरे भंडार से IQueryable को उजागर करने से, मुझे अंतर्निहित प्रदाता के बावजूद फ़िल्टर करने की अनुमति मिल जाएगी, जिससे मुझे प्रदाताओं के बीच स्विच करने की आवश्यकता हो। हालांकि ऊपर वर्णित समस्या मुझे सोचती है कि मुझे अपने सभी फ़िल्टरिंग को रिपॉजिटरीज़ में और आईनेमेरेबल, आईलीस्ट या सिंगल क्लासेस लौटाना चाहिए।

बहुत धन्यवाद, मैट

+0

झूठा आधार। 'BuildContainsExpression' * पूरी तरह से * ईएफ से स्वतंत्र है (यह केवल लिंक और अभिव्यक्तियों पर निर्भर करता है)। यह ईएफ 4 में भी पूरी तरह से अनावश्यक है, जो सीधे 'IEnumerable.Contains' का समर्थन करता है। –

उत्तर

14

यह एक बहुत ही लोकप्रिय सवाल है। एक जो मैं लगातार खुद से पूछता हूं। मुझे हमेशा एक भंडार से IQueryable के बजाय IENumerable लौटने के लिए सबसे अच्छा लगा है।

भंडार का उद्देश्य डेटाबेस आधारभूत संरचना को समाहित करना है ताकि क्लाइंट को डेटा स्रोत के बारे में चिंता न करें। हालांकि, यदि आप IQueryable लौटाते हैं तो आप उपभोक्ता की दया पर हैं कि आपके डीबी के खिलाफ किस प्रकार की क्वेरी चलती है, और क्या वे ऐसा कुछ करेंगे जो LINQ प्रदाता समर्थन नहीं करता है।

उदाहरण के लिए पेजिंग लें। मान लें कि आपके पास ग्राहक इकाई है और आपके डेटाबेस में सैकड़ों हजार ग्राहक हो सकते हैं। आप अपने क्लाइंट को किस कोड के बजाय लिखेंगे?

var customers = repos.GetCustomers().Skip(skipCount).Take(pageSize).ToList(); 

या

var customers = repos.GetCustomers(pageIndex, pageSize); 

पहले दृष्टिकोण में आप यह असंभव भंडार डेटा स्रोत से लिया गया अभिलेखों की संख्या को सीमित करने के लिए बनाते हैं। साथ ही, आपके उपभोक्ता को skipCount की गणना करनी है।

दूसरे दृष्टिकोण में आप अपने ग्राहक को अधिक मोटे अनाज वाले इंटरफ़ेस प्रदान करते हैं।अब आपकी रिपोजिटरी क्वेरी को अनुकूलित करने के लिए पेज साइज पर कुछ बाधाओं को लागू कर सकती है। आप skipCount की गणना को भी समाहित करते हैं।

हालांकि, कहा जा रहा है कि, आपकी स्थिति में आपका ग्राहक आपकी सेवा है। तो मुझे लगता है कि प्रश्न वास्तव में चिंताओं को अलग करने के लिए नीचे आता है। ऐसे सत्यापन तर्क करने के लिए बेहतर कहां है? वैसे यह जवाब "सेवा में" बहुत अच्छी तरह से हो सकता है। लेकिन "तर्क तर्क रखने में बेहतर कहां है" के जवाब के बारे में क्या? मेरे लिए जवाब स्पष्ट रूप से "रिपोजिटरी" है। यह विशेषज्ञता का अपना इच्छित क्षेत्र है।

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

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