سؤال

لا أفهم لماذا لا يعمل هذا الرمز.

foreach (DataRow dataRow in dataTable.Rows)
{
    if (true)
    {
        dataRow.Delete();
    }
}
هل كانت مفيدة؟

المحلول

بالرغم من DataRow.Delete لا يعدل حالة المجموعة ، وثائق Microsoft ينص على أنه يجب ألا تسميها أثناء التكرار على المجموعة:

لا يجب استدعاء حذف ولا إزالة في حلقة foreach أثناء التكرار من خلال كائن DataRowCollection. حذف أو إزالة تعديل حالة المجموعة.

أفضل حل هو إنشاء مجموعة منفصلة (على سبيل المثال أ List<DataRow>) من العناصر التي تريد إزالتها ، ثم إزالتها بعد لقد انتهيت من التكرار.

هذا هو أيضًا الحل للمواقف التي تريد إزالة العناصر من مجموعة ، حيث لا تسمح لك معظم المجموعات في .NET بتغيير محتويات المجموعة أثناء التكرار عليها.

نصائح أخرى

أكثر الطرق أمانًا - الاستخدام for عقدة

for (int i = datatable.Rows.Count - 1; i >= 0; i--) 
{
    if (true)
    {
        datatable.Rows[i].Delete();
    }
}

لا تنسى AcceptChanges لإزالة جميع الصفوف المميزة:

datatable.AcceptChanges();

لا يمكنك تعديل مجموعة أثناء التكرار عليها باستخدام أ foreach بيان.

يمكنك تجربة شيء من هذا القبيل:

List<DataRow> deletedRows = new List<DataRow>();

foreach (DataRow dataRow in dataTable.Rows)
{
    if(true) deletedRows.Add(dataRow);
}

foreach(DataRow dataRow in deletedRows)
{
    dataRow.Delete();
}

إذا اتصلت بالطريقة الحذف ، فعليك الاتصال فقط AcceptChanges() على الطاولة تقوم بتعديلها ، بعد حلقة foreach.

foreach (DataRow dataRow in dataTable.Rows)
{
    if (true)
    {
        dataRow.Delete();
    }
}

dataTable.AcceptChanges();

تمثل طريقة الحذف ببساطة الصف للحذف.

http://msdn.microsoft.com/en-us/library/system.data.datarow.delete٪28v=vs.90٪29.aspx

قد تكون إجابتي لم تعد مفيدة. استثناء رمي في Foreach مع DataRow لا يظهر إلا في .NET 2.0 وما قبل ذلك ، والسبب هو الوصف في MSDNhttp://msdn.microsoft.com/en-us/library/system.data.datarow.delete(v=vs.80).aspx

إذا تمت إضافة rowstate من الصف ، تتم إزالة الصف من الجدول.

يتم حذف Rowstate بعد استخدام طريقة Delete. يبقى حذفه حتى تتصل بـ AcceptChanges.

يمكن أن يتم إلغاء الصف المحذوف من خلال استدعاء الرفض.

لتمرير هذه المشكلة ، يمكنك الاتصال بـ datatable.acceptChanges () قبل استخدام Foreach

foreach (DataRow dataRow in dataTable.Rows)
{
    if (true)
    {
        dataRow.Delete();
    }
}

dataTable.AcceptChanges();

يرجى إحالة اللقطات إلى عدوى عملها.

  1. تم حذفها فقط ولكن لم تتم إزالتها من DataTable.

enter image description here

  1. نقطة الاستراحة قبل قبول accessChanges ().enter image description here
  2. بعد eexecuting وظيفة القبول ().enter image description here

آمل أن يتم حل هذه القضية الآن.

ال Rows يتغير المحتوى أثناء التكرار إذا قمت بحذف صف واحد ، مما يجعل التكرار غير صالح.

ومع ذلك ، يمكنك نسخ الصفوف إلى مجموعة أولاً ثم تكرارها على المجموعة وحذف الصفوف بهذه الطريقة. هذا يتأكد من أن التكرار لا ينقطع عن طريق تغيير البيانات إلى التكرار.

أسهل طريقة لتحقيق ذلك باستخدام قائمة لتعيين الصفوف التي تريد حذفها ثم حذف الصفوف خارج تكرار البيانات.

ج#

    List<DataRow> rowsWantToDelete= new List<DataRow>();

    foreach (DataRow dr in dt.Rows)
    {
        if(/*Your condition*/)
        {
            rowsWantToDelete.Add(dr);
        }
    }

    foreach(DataRow dr in rowsWantToDelete)
    {
        dt.Rows.Remove(dr);
    }

VB

Dim rowsWantToDelete As New List(Of DataRow)

For Each dr As DataRow In dt
    If 'Your condition' Then
        rowsWantToDelete .Add(dr)
    End If
Next

For Each dr As DataRow In rowsWantToDelete 
    dt.Rows.Remove(dr)
Next

هناك نسخة أخرى منه (أعتقد أنه أسهل) ما استخدمته للتو:

int i=0;
while (i < myDataTable.Rows.Count)
{
    if (condition)  //should it be deleted?
        myDataTable.Rows.RemoveAt(i);
    else
        i++;
}

هذا أسرع.

فقط للأشخاص الذين يبحثون عن سيناريو محدد مثلي ، كنت بحاجة إلى تقصير الوقت المستغرق ، وبمجرد استخراج بعض المعلومات المفيدة من كل صف ، استبعدت الصف عن طريق الحذف.

أتمنى أن يساعد هذا شخص ما ...

foreach (DataRow dataRow in dataTable.Rows)
{
    if (dataRow.RowState != DataRowState.Deleted)
    {
        if (your condition here)
        {
            dataRow.Delete();
        }
    }
}

هذا ينطبق على أي مجموعة إلى حد كبير. إذا حاولت حذف عنصر أثناء التغلب على المجموعة ، فستواجه مشكلة. على سبيل المثال ، إذا قمت بحذف الصف رقم 3 ، فإن الصف السابق رقم 4 يصبح الصف رقم 3.

حيث تحتوي العناصر على ملف Count, ، هذا ما فعلته:

int Count = myTable.Rows.Count;

while (Count > 0) // replace condition with myTable.Rows.Count if unconditionally performed on all rows
{
    DataRow row = myTable.Rows[0] // or however you want to find your index

    // do some work
    myTable.Rows.Remove(row);

    // if you want to perform a check to break out of while
    if (someCondition)
        Count = 0;
    else
        Count = myTable.Rows.Count;
}

لاحظ أن الكائنات تحتوي على ملف .GetXXXX() مجموعة ، مثل FileInfo (IIRC) ، حذف محتويات العناصر في أ foreach مقبولة. أحد الحلول التي فكرت فيها هو إنشاء طريقة تمديد توفر ملف .GetItems() طريقة.

استخدم هذا:

for (int i = 0; i < myDataTable.Rows.Count; i++)

{

 myDataTable[i].Delete();

}

هذا لأنه يبدو أنه يحاول تفكيك درج الدرج الذي تتسلقه. ببساطة ، لا يمكنك إزالة عنصر تكرره.

لذلك يجب عليك استخدام مجموعة مختلفة للتكرار وإزالتها من DataTable Rows منشأه.

foreach (DataRow dataRow in dataTable.Select())
{
    if (true)
    {
        dataTable.Rows.Remove(dataRow);
    }
}

أكد ماجنتس

هكذا فعلت ذلك ويعمل بشكل جيد

dt = GetStationeryConsolidationDetails(txtRefNo.Text);
int intRows = dt.Rows.Count;
int x = 0;
for (int c = 0; c < intRows; c++)
{
  if (dt.Rows[c - x]["DQTY"].ToString() == "0")
  {
    dt.Rows[c - x].Delete();
    dt.AcceptChanges();
    x++;        
  }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top