SQLDataAdapter.Update() не обновляется, когда RowState = Modified

Я пытаюсь настроить программу, которая, когда пользователь обновляет описание элемента, будет обновлять базу данных при сохранении формы. Я настроил все необходимое, но адаптер никогда не обновляется. Он отлично выбирает и вставляет, но никогда не обновляет. Код следующим образом:

  internal void UpdateDB(DataTable Items)
    {
      using ( var ItemsAdapter = new SqlDataAdapter("select * from dbo.Items", Properties.Settings.Default.ConnectionString) )
      using ( var ItemsCB = new SqlCommandBuilder(ItemsAdapter) )
      {
        ItemsAdapter.UpdateCommand = ItemsCB.GetUpdateCommand(true);
        ItemsAdapter.InsertCommand = ItemsCB.GetInsertCommand(true);
        ItemsAdapter.DeleteCommand = ItemsCB.GetDeleteCommand(true);

        ItemsAdapter.AcceptChangesDuringUpdate = true;
        foreach ( DataRow Row in Items.AsEnumerable() )
        {
          if ( !_Items.TableContains("Item", Row["Item"]) )
          { Row.AcceptChanges(); Row.SetAdded(); }
          else if ( _Items.TableContains("Item", Row["Item"]) )
          { Row.AcceptChanges(); Row.SetModified(); }
        }
        ItemsAdapter.Update(Items);

        _LoadAll();
      }
    }

Расширение .TableContains() — это домашнее расширение, которое я создал для проверки по таблице, чтобы увидеть, существует ли значение. Он работает идеально и устанавливает строки, в которых ПК уже существует, как измененные, а строки, в которых ПК не существует, в добавленные.

public static bool TableContains(this DataTable DT, string ColumnName, object ItemtoCheck)
{
  return DT.AsEnumerable()
           .Select(r => r.Field<string>(ColumnName))
           .ToList()
           .FindIndex(x => x.Equals(ItemtoCheck.ToString(), StringComparison.OrdinalIgnoreCase)) != -1;
}

Метод _LoadAll(); — это всего лишь метод перезагрузки всех DataTables после внесения изменений в базу данных.


person ARidder101    schedule 15.05.2018    source источник


Ответы (1)


Я понял, что я делаю неправильно. Я использовал таблицу, которая имела ссылку null в качестве исходного значения строки, и когда SQLDataAdapter.Update() выполнялась, она искала строку со значением null, которое не существовало и поэтому было проигнорировано. Чтобы исправить это, я изменил логику таблицы «Элемент» следующим образом:

    ItemsAdapter.AcceptChangesDuringUpdate = true;
    foreach ( DataRow Row in Items.AsEnumerable() )
    {
      if ( !_Items.TableContains("Item", Row["Item"]) )
      { ItemsTable.Rows.Add(Row); }
      else if ( _Items.TableContains("Item", Row["Item"]) )
      {
        ItemsTable.AsEnumerable()
                  .Join(Items.AsEnumerable(), r1 => r1.ItemArray[0], r2 => r2.ItemArray[0], (r1, r2) => new { r1, r2 })
                  .ToList()
                  .ForEach(i => i.r1.SetField(1, i.r2.ItemArray[1]));
      }
    }
    ItemsAdapter.Update(ItemsTable);

Это изменение установило новую таблицу, переданную методу обновления, для обновления моего внутреннего DataTable, в котором были значения базы данных, до нового обновления, а затем использовало это для обновления базы данных, и оно работало правильно.

Надеюсь, это может помочь любому, кто может столкнуться с той же проблемой, что и у меня.

person ARidder101    schedule 15.05.2018