2010-04-26 15 views
7

से हटाई गई पंक्तियों तक पहुंचने के लिए मेरे पास एक मूल WinForm है जिसमें एक सदस्य के रूप में MyDataTable _dt है। MyDataTable प्रकार विजुअल स्टूडियो 2005 (डेटाटेबल से MyDataTable विरासत) में "टाइप किए गए डेटासेट" डिज़ाइनर टूल में बनाया गया था _dt ADO.NET के माध्यम से डीबी से पॉप्युलेट हो जाता है। के रूप में उपयोगकर्ता बातचीत से परिवर्तन के आधार पर, मैं तो जैसे मेज से एक पंक्ति को हटा दें:डेटाटेबल

_dt.FindBySomeKey(_someKey).Delete();

बाद में, _dt एक संवाद फार्म के लिए मूल्य द्वारा पारित कर दिया है। वहाँ से, मैं एक स्ट्रिंग के निर्माण के लिए सभी पंक्तियों के माध्यम से स्कैन करने के लिए की जरूरत है:

  foreach (myDataTableRow row in _dt) 
      { 
       sbFilter.Append("'" + row.info + "',"); 
      } 

समस्या यह है कि एक को हटाने के बाद ऐसा करने पर निम्न अपवादों के फेंक दिया जाता है है: DeletedRowInaccessibleException: Deleted row information cannot be accessed through the row.

कि आसपास काम मैं वर्तमान में उपयोग कर रहा हूँ (जो एक हैक की तरह लगता है) पीछा कर रहा है:

  foreach (myDataTableRow row in _dt) 
      { 
       if (row.RowState != DataRowState.Deleted && 
        row.RowState != DataRowState.Detached) 
       { 
        sbFilter.Append("'" + row.info + "',"); 
       } 
      } 

मेरा प्रश्न: इस ऐसा करने के लिए उचित तरीका है? फोरैच लूप एक्सेस पंक्तियों को क्यों Delete() विधि के माध्यम से टैग किया गया है ??

+0

आपको 'अलग' की जांच करने की आवश्यकता नहीं है। – SLaks

उत्तर

2

आप जाँच करना होगा:

_dt.DefaultView.RowStateFilter 

मुझे लगता है कि डिफ़ॉल्ट सेटिंग नष्ट कर दिया पंक्तियों नहीं दिखाया जाएगा, हो सकता है आप इसे कहीं बदल जाते हैं।

आप हमेशा एक अतिरिक्त रोव्यूव बना सकते हैं और इसके फ़िल्टर को नियंत्रित कर सकते हैं और दृश्य पर अपना लूप कर सकते हैं।

+0

इससे तालिका के गणक को प्रभावित नहीं होगा। – SLaks

+0

@ स्लक्स: मैंने लिखा: 'और दृश्य पर लूप' –

+0

जो टाइप की गई पंक्तियों को खो देता है। – SLaks

14

Delete method हटाने के लिए एक पंक्ति को चिह्नित करता है; जब तक आप AcceptChanges पर कॉल नहीं करते हैं तब तक पंक्ति वास्तव में तब तक नहीं हटाई जाती है।

इसके बजाय, _dt.Rows.Remove(_dt.FindBySomeKey(_someKey)) पर कॉल करें, जो परिवर्तन को स्वीकार भी करेगा।
मानो या नहीं, Rows.Remove will completely remove the row, whereas row.Delete() won't
ध्यान दें कि यदि आप Rows.Remove पर कॉल करते हैं, तो पंक्ति स्थायी रूप से चली जाएगी, और डेटाएडाप्टर द्वारा डेटाबेस से हटाई नहीं जाएगी।

# 3 सी में, आपको निम्न विस्तार विधि के साथ अपने if बयान की जगह ले सकता:

static class Utils { 
    public static IEnumerable<TRow> CurrentRows(IEnumerable<TRow> table) where TRow : DataRow { 
     foreach(TRow row in table) { 
      if (row.RowState != DataRowState.Deleted) 
       yield return row; 
     } 
    } 
} 


foreach (myDataTableRow row in Utils.CurrentRows(_dt)) 
{ 

आप किए जा सकेंगे:

///<summary>Gets the rows in a typed DataTable that have not been deleted.</summary> 
public static EnumerableRowCollection<TRow> CurrentRows<TRow>(this TypedTableBase<TRow> table) where TRow : DataRow { 
    return table.Where(r => r.RowState != DataRowState.Deleted); 
} 

foreach (myDataTableRow row in _dt.CurrentRows()) 
{ 
    ... 

संपादित

यहाँ एक सी # 2 संस्करण है इस फ़ंक्शन को टाइप की गई तालिका के लिए आंशिक कक्षा में भी रखें:

partial class MyTable { 
    public IEnumerable<MyRow> CurrentRows() { return Utils.CurrentRows(this); } 
} 
+0

प्रतिक्रिया के लिए धन्यवाद। इसे इस तरह से करके, क्या मैं प्रभाव डालूंगा जब मैं अपनी तालिका को डीबी पर वापस अपडेट करने का प्रयास करता हूं? _dt.Update() क्या अपडेट() को DeleteCommand का उपयोग करके इस पंक्ति को हटाना है या यह "अच्छा के लिए चला गया है?" – Ken

+0

@ केन: नहीं, हटाए गए पंक्तियों को अपडेट के दौरान हटाया नहीं जाएगा _not_। निकालें! = –

+0

हटाएं @ केन: अच्छा बिंदु; मुझे लगता है कि कॉलिंग हटाने से 'अपडेट' इसे हटा नहीं पाएगा। कोशिश करो। – SLaks

0

मुझे इस बारे में निश्चित नहीं है, लेकिन मुझे लगता है कि अगर आप एक या अधिक पंक्तियों को हटाने के बाद _dt.AcceptChanges() पर कॉल करते हैं, तो आप डेटा तालिका के पंक्ति संग्रह के माध्यम से हटाए गए हटाए गए पंक्तियों को "देखें" नहीं देखेंगे।

+0

AcceptChanges पंक्ति स्थिति को हटा देता है, और मुझे बाद में इस स्थिति की आवश्यकता होती है जब मैं डीबी पर परिवर्तनों को जारी रखने के लिए _dt.Update() करता हूं। मैं अद्यतन के बाद शायद AcceptChanges() को कॉल करूंगा। धन्यवाद! – Ken

1

उपयोग GetChanges():

foreach (myDataTableRow row in _dt.GetChanges(DataRowState.Added)) 
{ 
    sbFilter.Append("'" + row.info + "',"); 
} 

आप सभी जोड़ा गया है और संशोधित करने के लिए चाहते हैं, बिटवाइज़ या जोड़ा गया पर और संशोधित का उपयोग करें:

foreach (myDataTableRow row in 
    _dt.GetChanges(DataRowState.Added | DataRowState.Modified)) 
{ 
    sbFilter.Append("'" + row.info + "',"); 
} 
+1

सही विचार, लेकिन यह वास्तव में एक कंपाइलर त्रुटि उत्पन्न करता है क्योंकि डेटाटेबल में सार्वजनिक GetEnumerator() विधि नहीं है। – Ken

+0

यह अपरिवर्तित पंक्तियों को वापस नहीं करेगा। – SLaks

+0

@ स्लक्स: गेट चेंज नाम के बावजूद, आप अपरिवर्तित पंक्तियां प्राप्त कर सकते हैं, _dt.GetChanges (DataRowSate.Unchanged) –

2

आप पंक्तियों को छोड़ कर रहे हैं क्या आपके पुनरावृत्ति में सही है, जब मैं डेटाटेबल पर लूप करता हूं तो मैं नियमित रूप से रोस्टस्टेट की जांच करता हूं जिसे संशोधित किया जा सकता है।

कुछ मामलों में मुझे विश्वास है कि पंक्ति को हटाए जाने से पहले आपको मूल पंक्ति मान चाहिए। किसी विशेष डाटरो मान को पुनर्प्राप्त करते समय एक द्वितीयक अनुक्रमणिका विकल्प होता है।

string st = dr["columnname", DataRowVersion.Original].ToString(); // c# 

dim st As String = dr("columnname", DataRowVersion.Original).ToString() ' vb.net 

मैं अतीत में इस बार कई बार अटक गया हूं।

जहां तक ​​गेटचैंज (रोस्टस्टेट) विधि का संबंध है, तो उस रौस्टेट की कोई पंक्ति नहीं होने पर, शून्य वापसी के लिए जांचना न भूलें, डेटाटेबल लौटाया गया है (मुझे लगता है कि इसे एक टेबल वापस करना चाहिए शून्य पंक्तियों के साथ)