问题
I am trying to set up a program that, when a user updates an item description, will update the database upon the save of the form. I have set up everything I have found that is required and yet the adapter never updates. It selects and inserts great but never update. Code as follows:
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();
}
}
The .TableContains()
extension is a home brew extension I built to check against the table to see if a value exists. It is running perfect and sets rows where the PK exists already to modified and rows where the PK does not exist to 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;
}
The _LoadAll();
method is just a method to reload all the DataTables
after the changes have been made to the database.
回答1:
I figured out what I was doing wrong. I was using a table that had a null
reference as its original row value and when the SQLDataAdapter.Update()
ran it was looking for a row with a null
value which did not exist and therefore was ignored. To fix this I changed my "Item" table logic as follows:
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);
This change set the new table passed to the update method to update my internal DataTable
that had the database values in it to the new update and then used that to update the database and it worked properly.
Hope this may help anyone who may end up with the same issue I had.
来源:https://stackoverflow.com/questions/50355328/sqldataadapter-update-not-updating-when-rowstate-modified