Возникло исключение при добавлении новых строк в datatable - PullRequest
1 голос
/ 20 августа 2010
  • listA - список целых чисел

  • dtListB - DataTable

Я проверяю, если StudentId из ListAне существует в dtListB, затем добавьте его в dtListB.

Dim stidListA, stIdListB As Integer

    For Each la In listA
        stidListA = la.StudentId

        For n = 0 To dtListB.Rows.Count - 1 Step 1
            stIdListB = dtListB.Rows(n)("StudentId")
            If stIdListB <> stidListA Then
    dtListB.Rows.Add(New Object() {la.StudentId, la.AssignedId, la.TimeSheetId, 0})
            End If
        Next
    Next

Я не уверен, почему выдается ошибка:

Исключение типа 'System.OutOfMemoryException' былоброшенный.

dtListB.Rows.Add (New Object () {la.StudentId, la.AssignedId, la.TimeSheetId, 0})

Anyпредложение?Спасибо.

Ответы [ 2 ]

1 голос
/ 20 августа 2010

Вы выполняете итерацию с dtListB.Rows и вставляете в dtListB.Rows.Это увеличивает Count и просто зацикливается на неопределенное количество времени.

0 голосов
/ 20 августа 2010

Проблема в том, что вы на самом деле не проверяете if StudentId of ListA doesn't exist in dtListB. На самом деле ваш код сравнивает КАЖДЫЙ элемент в dtListB с текущим элементом из ListA и, если они не совпадают, добавляет новую строку в dtListB. Предположим, у вас есть следующие списки:

ListA = { 3, 4 };
dtListB = { 1, 2, 3 };

Первая итерация для ListA, значение 3.

Check: (3 <> 1) and add '3' to dtListB (dtListB = { 1, 2, 3, 3 })
Check: (3 <> 2) and add '3' to dtListB (dtListB = { 1, 2, 3, 3, 3 })
Check: (3 <> 3) and don't do anything.
(Since the list has grown, you have two more iterations)

Для второй итерации для ListA со значением 4 вы вставите его 5 раз для каждого элемента существующего массива, с которым сравниваете, и получите результирующий список: { 1, 2, 3, 3, 3, 4, 4, 4, 4, 4 }. Очевидно, это не тот результат, которого вы ожидаете, и у вас, вероятно, есть большие списки и не хватает памяти.

Я бы предложил оставить флаг Boolean itemFound при циклическом просмотре dtListB. Установите его на False перед циклом, и, если обнаружен соответствующий элемент, установите на True. После цикла проверьте, является ли itemFound значением False, и, если да, добавьте элемент в список. Возможно, это неверный синтаксис VB, но вы поняли:

For Each la In listA
    stidListA = la.StudentId

    Dim itemFound as Boolean = False

    For n = 0 To dtListB.Rows.Count - 1 Step 1
        stIdListB = dtListB.Rows(n)("StudentId")
        If stIdListB <> stidListA Then
            itemFound = True
            Break //(is there Break in VB?)
        End If
    Next

    If Not itemFound Then
        dtListB.Rows.Add(New Object() {la.StudentId, la.AssignedId, la.TimeSheetId, 0})
    End If
Next
...