SQLDataAdapter.Update () не обновляется, когда RowState = Modified - PullRequest
0 голосов
/ 15 мая 2018

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

  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() является расширением для домашнего приготовления, которое я построил для проверки по таблице, чтобы увидеть, существует ли значение.Он работает идеально и устанавливает строки, в которых PK уже существует, для изменения, и строки, в которых PK не существует, в Added.

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после внесения изменений в базу данных.

1 Ответ

0 голосов
/ 15 мая 2018

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

    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, в котором были значения базы данных, до нового обновления, а затем использовал его для обновления базы данных, и она работала правильно.

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

...