2010-02-18 2 views
22

कोई व्यक्ति किसी भी कथन में डेटाकॉन्टेक्स्ट को लपेटने के बीच पेशेवरों/विपक्ष के बारे में अपनी राय में पिच कर सकता है या नहीं, LINQ-SQL में प्रदर्शन, स्मृति के रूप में कारकों के संदर्भ में उपयोग, कोडिंग में आसानी, सही काम करने के लिए आदिLINQ-SQL में, डेटाकॉन्टेक्स्ट को एक उपयोग कथन को लपेटें - पेशेवर विपक्ष

अद्यतन: एक विशेष आवेदन में , मैं अनुभव है कि, ब्लॉक का उपयोग करने में DataContext लपेटकर के बिना, स्मृति के उपयोग की मात्रा को लाइव वस्तुओं के रूप में बढ़ रही है पर रखा जीसी के लिए जारी नहीं किया गया था। जैसा कि नीचे दिया गया है, उदाहरण के लिए, यदि मैं q ऑब्जेक्ट की सूची और क्यू की एक्सेस इकाइयों के संदर्भ को संदर्भित करता हूं, तो मैं एक ऑब्जेक्ट ग्राफ़ बनाता हूं जो जीसी के लिए जारी नहीं होता है।

और का उपयोग किए बिना

using (DBDataContext db = new DBDataContext()) 
    { 
     var q = 
      from x in db.Tables 
      where x.Id == someId 
      select x; 

     return q.toList(); 
    } 

DataContext उपयोग करने के साथ DataContext रखा जिंदा

DBDataContext db = new DBDataContext() 
    var q = 
     from x in db.Tables 
     where x.Id == someId 
     select x; 

    return q.toList(); 

धन्यवाद।

+2

एक डुप्लिकेट की तरह दिखता है: http://stackoverflow.com/questions/821574/c-linq-to-sql-should-datacontext-be-disposed-using-idisposable/821595 – devuxer

+0

मैं जानना चाहता हूं स्मृति पर प्रभाव। – hIpPy

+0

http://stackoverflow.com/questions/821574/c-linq-to-sql-should-datacontext-be-disposed-using-idisposable/821595 के समान, धन्यवाद DanM। – hIpPy

उत्तर

12

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

डेटाकॉन्टेक्स्ट को एक छोटी सी वस्तु का उपयोग किया जाता है, इसका उपयोग करें, काम की इकाई प्राप्त करें, बाहर निकलें ... यह ठीक है कि आप इसका उपयोग कर रहे हैं।

तो फायदे:

  • जल्दी बंद कर दिया कनेक्शन
  • निपटाने से नि: शुल्क स्मृति (सामग्री में कैश्ड वस्तुओं)

नकारात्मक पहलू - अधिक कोड? लेकिन यह एक निवारक नहीं होना चाहिए, आप यहां using का उपयोग कर रहे हैं।

माइक्रोसॉफ्ट जवाब में यहाँ देखो: http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/2625b105-2cff-45ad-ba29-abdd763f74fe

आप using/.Dispose() उपयोग करने की आवश्यकता है, तो के लघु संस्करण:

संक्षिप्त उत्तर; नहीं, तुम करने की आवश्यकता नहीं है, लेकिन आप चाहिए ...

+2

जाहिर है, हमने डेटाकॉन्टेक्स्ट बनाने की जटिलता के बारे में विभिन्न बातें सुनी हैं। –

+0

@ जेम्स - हालांकि यह भारी नहीं है, ** अन्य चीजों के सापेक्ष ** यह है कि, मेरे वर्तमान ऐप में यह स्पूल अप करने के लिए सबसे भारी वस्तु है, यह हल्का वजन है, लेकिन आपकी औसत वस्तु से अभी भी भारी है। –

5

ठीक है, यह एक IDisposable है, तो मुझे लगता है कि यह एक बुरा विचार नहीं है। एमएसएफटी के लोगों ने कहा है कि उन्होंने डेटाकॉन्टेक्स को जितना संभव हो उतना हल्का बना दिया है ताकि आप उन्हें बेकार छोड़ दें, इसलिए शायद आप अधिक लाभ नहीं उठा रहे हैं .....

+0

यह वही जवाब है जब मुझे एक और सवाल पूछने पर प्राप्त हुआ।असल में, यह चोट नहीं पहुंचाता है और शायद मदद नहीं कर सकता है। – mark123

+3

@ mark123: केवल एक अपवाद के साथ, आप एक ही विधि के भीतर बनाते हैं, उपयोग करते हैं और समाप्त करते हैं, सभी को 'उपयोग' ब्लॉक में खपत किया जाना चाहिए। अन्यथा, लेखकों ने 'आईडीस्पोजेबल' को लागू करने के लिए चुना नहीं होगा। –

+0

मैं सहमत हूं। हमेशा इसे सही करने की कोशिश करें। मैं एक समस्या के माध्यम से जा रहा था जब मैं एक आईओसी कंटेनर (कैसल विंडसर) को एक भंडार से वस्तुओं को तुरंत चालू करने के साथ एक उपयोग ब्लॉक का उपयोग करने का तरीका जानने का प्रयास कर रहा था। इस मुद्दे पर जोर देते हुए मुझे बताया गया कि आईओसी कंटेनर निपटान() को संभालता है। मुझे उम्मीद है कि यह सही है क्योंकि यह वास्तव में समझ में आता है। – mark123

4

मैं आपके डेटा की जटिलता पर निर्भर करता हूं परत। यदि प्रत्येक कॉल एक साधारण एकल क्वेरी है, तो प्रत्येक कॉल को आपके प्रश्न में प्रयोग में लपेटा जा सकता है और यह ठीक होगा।

यदि दूसरी तरफ, आपका डेटा लेयर बिजनेस लेयर से कई अनुक्रमिक कॉल की अपेक्षा कर सकता है, तो आप बार-बार कॉल के प्रत्येक बड़े अनुक्रम के लिए डेटाकॉन्टेक्स्ट को बना/डिस्पोजेक्ट कर सकते हैं। आदर्श नहीं।

मैंने जो किया है वह मेरा डेटा लेयर ऑब्जेक्ट IDISposible के रूप में बनाना है। जब इसे बनाया जाता है, तो डेटाकॉन्टेक्स्ट बनाया जाता है (या वास्तव में, एक बार विधि के लिए पहली बार कॉल किया जाता है), और जब डेटा लेयर ऑब्जेक्ट डिस्पोजेक्ट करता है, तो यह डेटाकॉन्टेक्स्ट को बंद और डिस्पोजेक्ट करता है।

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Configuration; 

namespace PersonnelDL 
{ 
    public class PersonnelData : IDisposable 
    { 
     #region DataContext management 
     /// <summary> 
     /// Create common datacontext for all data routines to the DB 
     /// </summary> 
     private PersonnelDBDataContext _data = null; 
     private PersonnelDBDataContext Data 
     { 
      get 
      { 
       if (_data == null) 
       { 
        _data = new PersonnelDBDataContext(ConfigurationManager.ConnectionStrings["PersonnelDB"].ToString()); 
        _data.DeferredLoadingEnabled = false; // no lazy loading 
        //var dlo = new DataLoadOptions(); // dataload options go here 
       } 
       return _data; 
      } 
     } 

     /// <summary> 
     /// close out data context 
     /// </summary> 
     public void Dispose() 
     { 
      if (_data != null) 
       _data.Dispose(); 
     } 
     #endregion 

     #region DL methods 
     public Person GetPersonByID(string userid) 
     { 
      return Data.Persons.FirstOrDefault(p => p.UserID.ToUpper().Equals(userid.ToUpper())); 
     } 

     public List<Person> GetPersonsByIDlist(List<string> useridlist) 
     { 
      var ulist = useridlist.Select(u => u.ToUpper().Trim()).ToList(); 
      return Data.Persons.Where(p => ulist.Contains(p.UserID.ToUpper())).ToList(); 
     } 

     // more methods... 
     #endregion 
    } 
} 
1

एक विशेष आवेदन में, मैं अनुभव है कि, DataContextusing में ब्लॉक लपेटकर के बिना, स्मृति के उपयोग की मात्रा बढ़ती के रूप में जीवित वस्तुओं के लिए जारी नहीं किया गया पर रखा:

यहाँ यह क्या लग रहा है की तरह है जी सी। जैसा कि, उदाहरण के लिए, यदि मैं List<Table> ऑब्जेक्ट और q की एक्सेस इकाइयों का संदर्भ रखता हूं, तो मैं एक ऑब्जेक्ट ग्राफ़ बनाता हूं जो जीसी के लिए जारी नहीं होता है।

DBDataContext db = new DBDataContext() 
var qs = 
    from x in db.Tables 
    where x.Id == someId 
    select x; 

return qs.toList(); 

foreach(q in qs) 
{ 
    process(q); 
    // cannot dispose datacontext here as the 2nd iteration 
    // will throw datacontext already disposed exception 
    // while accessing the entity of q in process() function 
    //db.Dispose(); 
} 

process(Table q) 
{ 
    // access entity of q which uses deferred execution 
    // if datacontext is already disposed, then datacontext 
    // already disposed exception is thrown 
} 

इस उदाहरण को देखते हुए, मैं DataContext निपटान नहीं कर सकते क्योंकि सूची चर qs ** में सभी Table उदाहरणों में एक ही DataContext साझा करें। Dispose() के बाद, process(Table q) में इकाई तक पहुंचने से डेटाकॉन्टेक्स्ट पहले ही डिस्पोजेड अपवाद फेंकता है।

मेरे लिए बदसूरत क्लाउज, फोरच लूप के बाद q ऑब्जेक्ट्स के लिए सभी इकाई संदर्भों को हटाना था। बेशक using कथन का बेहतर तरीका है।

जहां तक ​​मेरा अनुभव जाता है, मैं कहूंगा कि using कथन का उपयोग करें।

5
  1. पहली बार डेटा कॉन्टेक्स्ट डीबी से ऑब्जेक्ट प्राप्त करेगा।
  2. अगली बार जब आप एक ही ऑब्जेक्ट (समान पैरामीटर) प्राप्त करने के लिए एक क्वेरी को फायर करते हैं .: आप प्रोफाइलर में क्वेरी देखेंगे लेकिन डेटाकॉन्टेक्स्ट में आपकी ऑब्जेक्ट को डीबी से नए स्थान पर नहीं बदला जाएगा !!

उल्लेख नहीं है कि प्रत्येक डेटाकॉन्टेक्स्ट के पीछे डीबी से पूछे जाने वाले सभी ऑब्जेक्ट्स का पहचान मानचित्र है (आप इसे आसपास रखना नहीं चाहते हैं)। DataContext की

पूरे विचार आशावादी संगामिति के साथ काम करें के यूनिट है। इसे छोटे लेनदेन के लिए उपयोग करें (केवल एक सबमिट करें) और निपटान करें।

निपटान को न भूलने का सबसे अच्छा तरीका()।

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