2009-01-20 14 views
44

मुझे लगता है कि मैं मंडलियों में चारों ओर दौड़ रहा हूं। मुझे लगता है कि सही भंडार पैटर्न LINQ to SQL का उपयोग कर रहा है, इस बारे में मेरा दिमाग नहीं लग रहा है। यदि आप Rob Conery'sMVC Storefront से परिचित हैं, तो आप देखेंगे कि उनका कार्यान्वयन LINQ- जेनरेट किए गए मॉडल को किसी अन्य वर्ग के साथ लपेटता है और LINQ- जेनरेट किए गए व्यक्ति को data transfer object (डीटीओ) के रूप में उपयोग करता है। यह इस तरह दिखता है:LINQ से SQL और रिपोजिटरी पैटर्न

//Custom wrapper class. 
namespace Data 
{ 
    public class Customer 
    { 
     public int Id {get;set;} 
     public string Name {get;set;} 
     public IList<Address> Addresses {get;set;} 
    } 
} 

//Linq-Generated Class - severly abbreviated 
namespace SqlRepository 
{ 
    public class Customer 
    { 
     public int Id {get;set;} 
     public string Name {get;set;} 
     public EntitySet<Address> {get;set;} 
    } 
} 

//Customer Repository 
namespace SqlRepository 
{ 
    public class UserRepository : IUserRepository 
    { 
     private _db = new DB(); //This is the Linq-To-Sql datacontext 

     public IQueryable GetCusomters() 
     { 
      return 
       from c in _db.Customers 
       select new Customer // This is the wrapper class not the gen'd one 
       { 
        Id = c.Id, 
        Name = c.Name, 
        Addresses = new LazyList(c.Addresses) 
       }; 
     } 

क्या यह इस तरह से कर रही है (एक आवरण वर्ग का प्रयोग करके) का लाभ है, के रूप में जिस तरह से माइक Hadlow Using the IRepository pattern with LINQ to SQL IRepository < टी के बारे में उनकी संस्करण में में पता चलता है करने के लिए विरोध> जहां वह सिर्फ डीटीओ वस्तुओं को भंडार से लौटाता है?

व्यापार तर्क को लागू और चेक किया जाना चाहिए? क्या यह अलग-अलग परत में सभी को एक साथ संग्रह/अद्यतन पर भंडार द्वारा बुलाया जाता है, या यह रैपर वर्ग में अंतर्निहित है?

उत्तर

48

बात यह है कि LINQ से SQL एक वास्तविक Object Relation Mapper (ORM) नहीं है, यह डेटा एक्सेस लेयर जेनरेटर है। आप एक्सएमएल फाइलों को संपादित करके गहराई से जाकर SqlMetal और व्हाट्नॉट के साथ खेलकर एक ओआरएम बना सकते हैं, लेकिन जहां यह चमकता है DAL के रूप में।

ओआरएम के पीछे विचार यह है। आपके पास आपका SQL डेटाबेस और आपकी डोमेन ऑब्जेक्ट्स हैं। डेटाबेस को सही तरीके से डिज़ाइन करने के लिए, आप चीजें करने जा रहे हैं (सामान्यीकरण की तरह) जो तर्कसंगत रूप से एक उचित ढंग से डिज़ाइन किए गए ऑब्जेक्ट मॉडल में अनुवाद नहीं करते हैं, और इसके विपरीत। इसे "इम्पैडेंस मिस्चैच" कहा जाता है, एक ओआरएम की भूमिका एक स्वच्छ, प्रभावी और कुशल तरीके से उस विसंगति से निपटना है। कम दर्दनाक डेटाबेस इंटरैक्शन लगभग एक माध्यमिक चीज है।

एक भंडार के पीछे विचार यह है कि यह आपके शेष आवेदन से बुनियादी ढांचे पर सभी दृढ़ता तर्क और निर्भरताओं को समाहित करता है। जब आपके एप्लिकेशन को ग्राहक ऑब्जेक्ट की आवश्यकता होती है, तो उसे यह नहीं पता होना चाहिए कि यह SQL सर्वर, MySQL, एक XML फ़ाइल, या ASP.NET सदस्यता से आ रहा है या नहीं। एक बार जब आप डी-युग्मन कर लेते हैं, तो आपके दृढ़ता की कहानी में किए गए कोई भी बदलाव आपके शेष एप्लिकेशन पर कोई प्रभाव नहीं डालते हैं।

इस बात को ध्यान में रखते हुए, यह और स्पष्ट हो गया कि उसने ऐसा क्यों किया। LINQ से SQL का उपयोग डीएएल उत्पन्न करने के लिए किया जाता है, लेकिन डीएएल के बारे में जाना जाने वाला एकमात्र चीज भंडार है, इसलिए अनुवाद उनके डोमेन ऑब्जेक्ट्स में किया जाता है। इस तरह वह अपने दृढ़ता की कहानी के बारे में चिंता किए बिना अपने डोमेन मॉडल को दोबारा कर सकता है, और वह अपने आवेदन के माध्यम से प्रभाव को छेड़छाड़ करने के बारे में चिंता किए बिना अपने डेटाबेस को दोबारा कर सकता है। वह ओआरएम का उपयोग करने के लिए या यहां तक ​​कि अपने डेटा को स्टोर करने के तरीके जैसे प्रश्नों पर निर्णय लेने से पहले व्यवसाय तर्क पर कोडिंग शुरू कर सकता है।

यदि वह वास्तविक ओआरएम (जैसे NHibernate) का उपयोग करना था, तो मैपिंग कोड कहीं और संभाला जाता है (या तो एक्सएमएल या बूटस्ट्रैपिंग कक्षाओं में)। मुझे लगता है कि LINQ से SQL (और रोब्स ओपन सोर्स डीएएल, SubSonic) महान परियोजनाएं हैं, लेकिन छोटे, दो-स्तरीय अनुप्रयोगों के लिए अधिक डिज़ाइन किया गया है जहां रिपोजिटरी पैटर्न की तरह कुछ अधिक है। स्टोरफ्रंट भी एक अच्छा उदाहरण है कि एनएचबीरनेट की अतिरिक्त जटिलता क्यों महत्वपूर्ण हो सकती है। वह मैन्युअल रूप से ऐसा करने के बजाय, उस तरह के परिदृश्य को संभालने के लिए बनाए गए कुछ चीज़ों के साथ जाकर खुद को बहुत से कोड बचा सकता था।

+0

लेकिन जब आप NHIBERNATE की तरह कुछ स्विच करते हैं तो आप अपने भंडार में उपयोग किए गए एसक्यूएल एक्सटेंशन विधियों के साथ linq के साथ क्या करते हैं? एक नया भंडार बनाएँ? – zsharp

+0

यह एक महान स्पष्टीकरण है। समस्या मुझे लगता है कि बहुत से लोगों के पास है (पढ़ें "मैं") एल 2 एस ऑब्जेक्ट्स को पूरी तरह से एक डीएएल के अलावा कुछ और करने का प्रयास कर रहा है। लेकिन सत्यापन के लिए सभी प्रकार के हुक बनाने के लिए उस एमएस की गलती का हिस्सा नहीं है? – Micah

+1

2-स्तरीय आर्किटेक्चर के साथ कुछ भी गलत नहीं है, अगर यह आवश्यक है। उस स्थिति में, एल 2 एस एक अच्छा उत्पाद है, और मॉडल उत्पन्न करने वाली मॉडल ऑब्जेक्ट्स बहुत अनुकूलन और एक्स्टेंसिबल हैं। समस्या एन-स्तरीय पैटर्न तक बढ़ रही है, मुझे लगता है कि एल 2 एस जैसे प्रोजेक्ट को तोड़ना शुरू हो जाता है –

12

यह इस बात पर निर्भर करता है कि DTOs कहां परिभाषित किया गया है और आप इसका परीक्षण कैसे करना चाहते हैं। यदि आप डीबीएमएल का उपयोग करते हैं, तो LINQ से SQL डेटा डेटा में डेटा ऑब्जेक्ट जेनरेट करना चाहता है। जबकि LINQ से SQL निरंतर अज्ञानता का समर्थन करता है, यह इसे आसान बनाने के अपने रास्ते से बाहर नहीं जाता है। Entity Framework बिल्कुल इसका समर्थन नहीं करता है।

इसका मतलब है कि मानक मॉडल में, आपकी डेटा परत सभी डोमेन इकाइयों को परिभाषित कर रही है, जो कि यदि आप डेटा इंटरफ़ेस से वास्तविक अलगाव में उपयोगकर्ता इंटरफ़ेस/व्यावसायिक परतों का परीक्षण करना चाहते हैं तो यह मुश्किल है।

यूनिट परीक्षणों में डेटा परत से डेटा ऑब्जेक्ट परिभाषाओं का उपयोग करने के लिए एक व्यावहारिक दृष्टिकोण हो सकता है, लेकिन डेटा-संदर्भ नहीं (यानी भंडार इंटरफ़ेस के पीछे डेटा-संदर्भ को छुपाएं, लेकिन इकाई प्रकारों का पर्दाफाश करें) - लेकिन यह पानी को थोड़ा सा गड़बड़ कर रहा है, और इसका मतलब है कि आपका यूआई, आदि डेटा परत को दृढ़ता से संदर्भित करने की आवश्यकता है। लेकिन यदि आप इसे "डोमेन मॉडल परत" के रूप में सोचते हैं जिसमें एक रिपोजिटरी कार्यान्वयन भी होता है जिसे हम उपयोग कर सकते हैं या नहीं भी हो सकता है "तो आप इसे औचित्य दे सकते हैं।

पूरी तरह से अलग डोमेन इकाइयों को रखने से यूनिट परीक्षण और inversion of control (आईओसी) अधिक "शुद्ध" बनाता है, लेकिन आपके पास मौजूद कोड की मात्रा बढ़ जाती है (इसलिए डबल-एज)।

2

क्या उत्पन्न वस्तुएं क्रमबद्ध हैं? मुझे लगता था कि वे नहीं थे। मार्क अलवेल ने उपरोक्त कहा है कि यह अलगाव का मामला है।

क्या होगा यदि आप रिपोजिटरी स्विच करते हैं और एक MySQL, ओरेकल, एक्सएमएल फाइलें, वेब सेवा, या जो भी डेटा प्रदाता (रिपोजिटरी) है? आप इकाइयों का संदर्भ देने के लिए LINQ से SQL असेंबली से बंधे होंगे, है ना? कौन सा, आप चाहते हैं, नहीं।

+0

आप उन्हें एक विकल्प के रूप में क्रमबद्ध कर सकते हैं। – Micah

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