2012-02-23 17 views
5

मैं रिपोजिटरी पैटर्न का उपयोग कर रहा हूं जहां मेरे पास प्रति डेटाबेस तालिका में एक रिपोजिटरी क्लास है। मैं सोच रहा था कि कैसे तुम लोगों के प्रश्नों है कि केवल कॉलम की एक विशिष्ट संख्या लौटना ही होगा दृष्टिकोणरिपोजिटरी पैटर्न और रिटर्न प्रकार

उदाहरण के लिए कहते हैं कि मैं निम्नलिखित

आइटम टेबल (काल्पनिक तालिका) है

ItemId 
Name 
PurchaseDate 
Description 
Price 

में मेरी कोड मैं उपरोक्त फ़ील्ड के साथ एक आइटम बना देता हूं जिसे Item.cs कहा जाता है (वर्तमान में एक ओआरएम का उपयोग नहीं कर रहा है)।

अगर मैं अनेक परिदृश्यों जहाँ मैं

  1. Itemid
  2. PurchaseDate और नाम
  3. Itemid का एक संयोजन वापस जाने के लिए की जरूरत है और कीमत

कौन सा सबसे अच्छा तरीका हो सकता है है?

  1. आइटम मेज से सभी क्षेत्रों जाओ और एक मद वस्तु (1 रेपो क्वेरी)
  2. रेपो में तीन प्रश्नों बनाएं लौट सकते हैं और हर एक
  3. के लिए एक आइटम ऑब्जेक्ट प्रदान रेपो में तीन प्रश्नों बनाएँ और केवल वापसी क्या ज़रूरत है?

अब इस परिदृश्य को 10 से अधिक फ़ील्ड वाली तालिका के साथ कल्पना करें।

व्यक्तिगत रूप से, मुझे विकल्प एक पसंद है, लेकिन मुझे यकीन नहीं है कि इसके बारे में जाने का बेहतर तरीका है या नहीं।

उत्तर

6

मैं व्यक्तिगत रूप से एक सामान्य प्रकार भंडार का उपयोग करें और और मेरी है पढ़ AsQueryable()

यहां इंटरफ़ेस है।

interface IRepository<T> 
{ 
    void Create(T item); 
    IQueryable<T> Retrieve(); 
    void Update(T item); 
    void Delete(T item); 
    void SubmitChanges(); 
} 

और यहां कार्यान्वयन है।

public class PersonsRepository : IRepository<Person> 
{ 
    private DataContext dc; 

    public PersonsRepository(DataContext dataContext) 
    { 
     dc = dataContext; 
    } 

    public void Create(Person Person) 
    { 
     dc.Persons.Add(Person); 
    } 

    public IQueryable<Person> Retrieve() 
    { 
     IQueryable<Person> Person = (from s in dc.Persons 
             select s); 
     return Person.AsQueryable(); 

    } 

    public void Update(Person Person) 
    { 
     Person _Person = (from s in dc.Persons 
          where s.ID == Person.ID 
          select s).Single(); 
     { 
      _Person.LastLogin = Person.LastLogin; 
      _Person.Password = Person.Password; 
      _Person.LastUpdate = Person.LastUpdate; 
      // Cannot change your username. 
     } 
    } 

    public void Delete(Person Person) 
    { 
     dc.Persons.Remove(Person); 
    } 

    public void SubmitChanges() 
    { 
     dc.SaveChanges(); 
    } 
} 

अब यदि आपको रिपोजिटरी से पूछताछ की आवश्यकता है, तो आप ऐसा कुछ करना चाहते हैं।
मुझे माफ कर दो, नीचे दिए गए कोड अपरीक्षित है और मैं वास्तव में एक वीबी पुरुष :(
उम्मीद है कि आप समझ गए

public class PersonsService 
{ 
    private PersonRepository<Person> personRepository; 

    public PersonService() 
    { 
     personRepository = new PersonRepository<Person>(); 
    } 

    public UsablePerson GetPersonByID(int ID) 
    { 
     UsablePerson person = (from p in personRepository<Person>.Retrieve 
           where p.ID = ID 
           select new UsablePerson { p.FirstName, 
                 p.LastName, 
                 p.EmailAddress }).FirstOrDefault(); 

     return person; 
    } 
} 

मेरी प्रयोजनों के लिए की अधिक हूँ, मैं इस विशेष पर LINQ उपयोग कर रहा हूँ प्रोजेक्ट, लेकिन यह आपको जो भी डेटा लेयर पसंद है उसे अनुकूलित किया जा सकता है ... यह एक रिपोजिटरी परत की सुंदरता है।

यहां से मैं "व्यक्तिगत" में एक सेवा परत भी है जो डेटा कनेक्शन की बारीकियों से संबंधित है ... GetPersonByID या GetPeopleSince(DateTime marker) जैसी चीज़ें। यह वह जगह है जहां मैंने सूचना को बाहर निकाला टयन जो मुझे चाहिए (आईई: पासवर्ड) और शेष जानकारी को व्यूमोडेल या किसी अन्य पीओसीओ में स्टोर करें।

+0

बस यह देखने के लिए कि क्या मैं एक ही पृष्ठ पर हूं। अधिक विशिष्ट प्रश्नों के लिए (GetPersonByID) के लिए आप रेपो से पूरे व्यक्ति रिकॉर्ड वापस कर देते हैं और फिर सेवा परत में सभी अनियंत्रित जानकारी को बाहर कर देते हैं और केवल आईडी लौटाते हैं? क्या आप इसका एक उदाहरण दिखा सकते हैं, क्योंकि यही वह है जिसके साथ मुझे कठिन समय है। मुझे यकीन नहीं है कि मुझे बहुत से रेपो विधि बनाना चाहिए या सिर्फ एक है जो हमेशा सभी टेबल कॉलम (यानी पूरी पंक्ति) देता है – chobo

+0

मैंने स्मृति से अपना सर्वश्रेष्ठ प्रयास किया ... मेरे पास मेरे सामने मेरा आईडीई नहीं है इसलिए उपर्युक्त उदाहरण में शायद कुछ त्रुटियां हैं। उम्मीद है कि आपको तस्वीर मिल जाएगी। –

+0

मुझे वह तकनीक पसंद है क्योंकि यह रेपॉजिटरीज़ में विधियों की संख्या में कटौती करता है। लेकिन, मुझे हमेशा सिखाया जाता था कि आपको केवल डेटाबेस से आवश्यक कॉलम लौटाएंगे, ऐसा लगता है कि एक रिपोजिटरी के साथ आप हमेशा एक इकाई प्रकार या इकाई संग्रह लौट रहे हैं। क्या यह रिपोजिटरी पैटर्न का इरादा है? हो सकता है कि मैं डेटाबेस प्रदर्शन प्रभाव – chobo

0

मुझे इस तरह की चीज़ के लिए लिंक-आधारित रिपॉजिटरीज़ पसंद है।Linq2SQL, एमएसईएफ, या Linq2NH आपकी कॉलम सूची को परिभाषित करने के लिए, चयन() विधि के माध्यम से, आपको अनुमति देगा। इसके बाद आपको केवल एक डोमेन ऑब्जेक्ट या एंटिटी क्लास प्राप्त होगा जो आपने निर्दिष्ट किया है। आपके पास डीटीओ में इसे मैप करने के लिए अतिरिक्त कोड हो सकता है, या केवल डोमेन क्लास का उपयोग करके यह जानकर कि यह पूरी तरह से "हाइड्रेटेड" नहीं है।

2

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

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

मैं LINQ से SQL को एक डीएएल के रूप में पसंद नहीं करता, क्योंकि @ केथिस ने सुझाव दिया है, लेकिन मैं एंटरप्राइज़ एनवायरनमेंट में काम करता हूं और LINQ से SQL मूल रूप से स्केल पर बेकार है। LINQ का उपयोग करना अन्यथा महान है। केवल मेरे दो सेंट्स।

यदि आप एक ऑब्जेक्ट प्रकार वापस कर सकते हैं, तो यह बेहतर है। यदि ऑब्जेक्ट्स में अंतर अनुमतियों पर आधारित है, तो उस डेटा को साफ़ करने पर विचार करें जिसे उपयोगकर्ता को नहीं देखना चाहिए। नोट, हालांकि, यदि आप बड़ी संख्या में ऑब्जेक्ट्स को पकड़ रहे हैं तो यह स्केलेबल नहीं है।

+0

+1 अच्छा जवाब। – jgauffin

+1

मैं केवल रेपो से एक ऑब्जेक्ट प्रकार लौटाता हूं, लेकिन मुझे क्या चल रहा है क्या मुझे हमेशा एक इकाई वस्तु वापस करनी चाहिए? उदाहरण के लिए यदि मेरे पास GetEmployeeID नामक एक विधि है, तो क्या मुझे केवल उस क्षेत्र के साथ कर्मचारी ऑब्जेक्ट वापस करना चाहिए? या मुझे सिर्फ एक कर्मचारी संख्या वापस करनी चाहिए? क्या मुझे सिर्फ एक getEmployee विधि का उपयोग करना चाहिए या क्या मुझे GetEmployeeId बनाम रेपो में अधिक विशिष्ट तरीकों से इसे तोड़ना चाहिए? – chobo

5

मैं अपने भंडारों में विधियों को जोड़ता हूं जब मुझे सामान्य भंडारों के विपरीत उनकी आवश्यकता होती है जहां आपको विधियों का एक सेट मिलता है चाहे आप उन्हें चाहिए या नहीं।

रिटर्निंग IQueryable एक रिसाव अमूर्त है।

डोमेन संचालित डिजाइन (पुस्तक) पर एक नज़र डालें और आपको एक अच्छा विचार मिलेगा कि डिज़ाइन किए गए रिपॉजिटरीज़ कैसा दिखना चाहिए।

मैं भी सामान्य खजाने बारे में एक शेख़ी लिखा है: http://blog.gauffin.org/2012/02/generic-repositories-a-silly-abstraction-layer/

+0

सहमत है, 'IQueryable' लौटने से आप जो कुछ करना चाहते हैं उसके विपरीत काफी विपरीत कर रहे हैं - यह केवल आपकी डोमेन परत में बुनियादी ढांचागत चिंता है। – davenewza

0

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

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