2009-02-14 7 views
15

मेरे विस्तारित LinqToSql कक्षाओं में आसान पहुंच के लिए मेरे डेटाकॉन्टेक्स्ट को स्थापित करने के मामले में सबसे अच्छा अभ्यास क्या है?LinqToSql घोषित करें और DataContext सर्वोत्तम अभ्यास को तुरंत चालू करें?

उदाहरण के लिए, मैं अपने dbml में एक "उपयोगकर्ता" इकाई है और मैं तो जैसे कि वर्ग के लिए तरीकों जोड़ना चाहते हैं:

Partial Public Class User 

    Public Function GetUser(ByVal UserID as Integer) as User 
     'Do Work 
    End Function 

End Class 

मेरी DataContext उपयोग करने के लिए मैं इसे अंदर घोषित करने के लिए होगा इस प्रकार की विधि:

Partial Public Class User 

    Public Function GetUser(ByVal UserID as Integer) as User 
     Dim dc as New MyDataContext() 
     Return (From u in dc.Users Where u.ID = UserID).Single() 
    End Function 

End Class 

मैं प्रत्येक विधि के लिए ऐसा नहीं करना चाहता हूं। आम तौर पर (अगर मैं LinqToSql dbml कक्षाओं का विस्तार नहीं किया गया) मैं तो बस ऐसा कर सकता है:

Partial Public Class User 
    Private dc as MyDataContext 

    Public Sub New() 
     dc = new MyDataContext() 
    End Sub 

    Public Function GetUser(ByVal UserID as Integer) as User 
     Return (From u in dc.Users Where u.ID = UserID).Single() 
    End Function 

    Public Function GetAllUsers() as IEnumerable(Of User) 
     Return From u in dc.Users 
    End Function 

    'etc... 

End Class 

यह मैं नव हर बार यह घोषणा करने के लिए बिना प्रत्येक विधि के लिए DataContext तक पहुंच सकते हैं। लेकिन निश्चित रूप से आप ऐसा नहीं कर सकते क्योंकि डीबीएमएल में पहले से ही एक कन्स्ट्रक्टर है। और डीबीएमएल में कोड जोड़ना हमेशा कुछ भी बदल जाता है अगर कुछ भी बदलता है।

किसी के पास कुछ अतिरिक्त कोड कैसे सहेजने के बारे में कोई अच्छा विचार है?

टीआईए!

उत्तर

13

सबसे पहले, सुनिश्चित करें कि आप अपना डेटा कॉन्टेक्स्ट का निपटारा कर रहे हैं! वह एक भारी छोटी कमी हो सकता है ( संपादित करने के लिए भारी नहीं है, लेकिन यदि आप इसे बिना निपटाने के उपयोग करते रहते हैं तो आसपास रखना भारी है); आप पुरानी डेटाकॉन्टेक्स को स्मृति में चारों ओर लटकना नहीं चाहते हैं।

दूसरा, डेटाकॉन्टेक्स्ट का उद्देश्य एक लॉजिकल लेनदेन का प्रतिनिधित्व करना है। जैसे हर बार जब आप एक नया लेनदेन शुरू करना चाहते हैं, तो आपको एक नया निर्माण करना चाहिए, और लेनदेन पूरा होने पर इसे से छुटकारा पाएं। तो आपके उद्देश्यों के लिए, शायदGetUser विधि का दायरा है। यदि आपके पास डीबी कॉल की एक श्रृंखला है जिसे समूह के रूप में बनाने की आवश्यकता है, तो उन्हें इसे से छुटकारा पाने से पहले सभी डीसी का उपयोग करना चाहिए।

+1

डेटा संदर्भ स्वयं वास्तव में बहुत हल्का है, हालांकि यह संभावित रूप से कई संस्थाओं का संदर्भ दे सकता है। संस्थाओं को मुक्त करने के लिए इसका निपटारा वास्तव में एक अच्छा विचार है। यदि यह हेवीवेट ऑब्जेक्ट था तो मैं इसे चारों ओर रखने के इच्छुक हूं इसलिए मुझे इसे फिर से बनाना नहीं था। – tvanfosson

+0

@tvanfosson मेरा मतलब है; उस बिंदु को और स्पष्ट करने के लिए संपादित किया गया। डीसी संभावित रूप से इसके साथ बहुत अधिक वजन ले सकता है; जितनी जल्दी हो सके इसे से छुटकारा पाने के लिए सबसे अच्छा। –

+0

निपटान के खिलाफ तर्क: http://stephenwalther.com/blog/archive/2008/08/20/asp-net-mvc-tip-34-dispose-of-your-datacontext-or-don-t.aspx –

0

मुझे लगता है कि शायद वास्तविक समस्या यह है कि User संभवत: एक उदाहरण सदस्य कॉल GetUser के लिए सही जगह नहीं है।

+0

इसका मतलब क्या है? क्या आप आगे समझा सकते हैं? – EdenMachine

11

Rex M said के रूप में, डेटाकॉन्टेक्स्ट का उद्देश्य प्रत्येक तार्किक लेनदेन के लिए तत्काल, उपयोग और निपटान किया जाना है। इस तरह के पैटर्न को कभी-कभी "काम की इकाई" कहा जाता है।

ऐसा करने का सबसे आम तरीका (जो मुझे पता है) एक उपयोग ब्लॉक में अपने डेटाकॉन्टेक्स्ट को तुरंत चालू करना है। मैं एक समय में एक वीबी का इस्तेमाल किया है नहीं है, लेकिन यह कुछ इस तरह दिखना चाहिए: (कोड का भौतिक आकार के माध्यम से)

Using dc As New MyDataContext() 
    user = (From u in dc.Users Where u.ID = UserID).Single() 
End Using 

यह न केवल पुष्ट काम का एक लेन-देन/इकाई के देखो, लेकिन यह ब्लॉक समाप्त होने पर आपके डेटाकॉन्टेक्स्ट पर निपटान() को कॉल करना सुनिश्चित करता है।

this MSDN page देखें:

सामान्य तौर पर, एक DataContext उदाहरण एक " काम की इकाई" के लिए पिछले करने के लिए बनाया गया है लेकिन अपने आवेदन है कि इस शब्द को परिभाषित करता है।डेटाकॉन्टेक्स्ट हल्का वजन है और बनाने के लिए महंगा नहीं है। एक विशिष्ट LINQ से SQL एप्लिकेशन विधि स्कोप पर डेटाकॉन्टेक्स्ट उदाहरण बनाता है या अल्पकालिक वर्गों के सदस्य संबंधित डेटाबेस संचालन के लॉजिकल सेट का प्रतिनिधित्व करता है।

0

इस बारे में कुछ अलग-अलग तरीके हैं जिनके बारे में आप जा सकते हैं, यह अच्छा अभ्यास होगा, मुझे लगता है। सबसे पहले आप एक रिपोजिटरी पैटर्न का उपयोग कर सकते हैं जहां आप किसी ऑब्जेक्ट के लिए रिपोजिटरी से पूछताछ करते हैं, यह डेटाबेस पर जाता है, ऑब्जेक्ट को पुनर्प्राप्त करता है - शायद डेटा संदर्भ से इसे अलग करता है या रिपोजिटरी के कार्यान्वयन के आधार पर डेटा संदर्भ को रखता है - और यह आपको वापस देता है। आपकी वस्तुओं के लिए फैक्ट्री विधियां रिपोजिटरी पर होंगी, न कि संस्थाएं स्वयं। आप संभवत: लागू करने के तरीकों की संख्या को कम करने और अपना कोड DRY रखने के लिए प्रतिबिंब और जेनेरिक का उपयोग करेंगे।

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

दूसरी ओर, आप अपने स्वयं के समाधान में उपरोक्त में से किसी एक को दोहराने के बजाय nHibernate या कैसल के ActiveRecord का उपयोग कर देख सकते हैं।

0

यदि आप अकेले उपयोगकर्ता कक्षा छोड़ते हैं और आईडीई को इसके निर्माण को संभालते हैं तो यह आसान हो सकता है।

अक्सर मैं अलग-अलग कक्षा डेटा पुनर्प्राप्ति को संभालना पसंद करता हूं। आइए मान लें कि आप इसे UserDataProvider कहते हैं और उपयोगकर्ता कॉल प्राप्त करने के लिए सभी कॉल अंततः इस कक्षा के माध्यम से जाते हैं।

उपयोगकर्ता डेटा प्रदाता का निर्माता पुन: उपयोग के लिए डेटा संदर्भ ऑब्जेक्ट का वैश्विक उदाहरण तत्काल कर सकता है। यह (मेरे साथ सी # और untested कोड तो नंगे में) कुछ इस तरह दिखेगा:

public class UserDataProvider 
{ 
    private UserDataContext _data = null; 

    public UserDataProvider() 
    { 
     _data = new UserDataContext(); 
    } 

    public User GetUser(int userID) 
    { 
     return _data.Users.FirstOrDefault(u => u.UserID == userID); 
    } 
} 

वैकल्पिक रूप से, आप एक संपत्ति में प्रारंभ और उपयोग पर रख सकती है कि डेटा संदर्भ के उपयोग के लिए संपत्ति।

public class UserDataProvider 
{ 
    private UserDataContext _dataContext; 

    private UserDataContext DataContext 
    { 
     get 
     { 
      if (_data == null) 
       _data = new UserDataContext(); 

      return _data; 
     } 
    } 

    public User GetUser(int userID) 
    { 
     return DataContext.Users.FirstOrDefault(u => u.UserID == userID); 
    } 
} 
संबंधित मुद्दे