Bun*_*top 6 c# postgresql npgsql
我正在尝试编辑DataTable
填充NpgsqlDataAdapter
.在调用Fill()
方法之后,我只有一行DataTable
.然后我只更改了一列的值,并尝试更新如下.
然后我收到这个错误:
发生了DBConcurrencyException
我的代码是:
NpgsqlDataAdapter getAllData = new NpgsqlDataAdapter("SELECT sn,
code,product, unitprice, quantity, InvoiceNo, Date FROM stocktable WHERE Code='" + product + "'
ORDER BY EDate ASC", DatabaseConnectionpg);
DataTable ds1 = new DataTable();
ds1.Clear();
getAllData.Fill(ds1);
if (ds1.Rows.Count > 0)
{
ds1.Rows[0]["Quantity"] = qty;// calculated value
}
ds1 = ds1.GetChanges();
NpgsqlCommandBuilder cb = new NpgsqlCommandBuilder(getAllData);
//getAllData.RowUpdating += (sender2, e2) => { e2.Command.Parameters.Clear(); };
//cb.SetAllValues = false;
getAllData.DeleteCommand = cb.GetDeleteCommand();
getAllData.InsertCommand = cb.GetInsertCommand();
getAllData.UpdateCommand = cb.GetUpdateCommand();
int x = getAllData.Update(ds1);
if (x > 0)
{
ds1.AcceptChanges();
}
Run Code Online (Sandbox Code Playgroud)
编辑:我有三个字段作为主键,我只在select语句中调用两个字段.这是DBConcurrency
错误的原因吗?但我能够在SQL Server 2005中使用相同的(三个字段作为主键)参数更新表.
更新:
我找到了解决方案,解决方案是我创建并使用第二个DataAdapter来更新数据.我使用getAllData(NpgSqlDataAdapter)将表填充为
NpgsqlDataAdapter getAllData = new NpgsqlDataAdapter("SELECT
code,product, unitprice, quantity, InvoiceNo, Date FROM stocktable WHERE Code='" + product + "'
ORDER BY EDate ASC", DatabaseConnectionpg);
Run Code Online (Sandbox Code Playgroud)
并创建了下一个适配器以更新为
NpgsqlDataAdapter updateadap= new NpgsqlDataAdapter("SELECT sn, quantity FROM stocktable WHERE Code='" + product + "'
ORDER BY EDate ASC", DatabaseConnectionpg);
NpgsqlCommandBuilder cb = new NpgsqlCommandBuilder(updateadap);
//getAllData.RowUpdating += (sender2, e2) => { e2.Command.Parameters.Clear(); };
//cb.SetAllValues = false;
updateadap.DeleteCommand = cb.GetDeleteCommand();
updateadap.InsertCommand = cb.GetInsertCommand();
updateadap.UpdateCommand = cb.GetUpdateCommand();
int x = updateadap.Update(ds1);
if (x > 0)
{
......
}
Run Code Online (Sandbox Code Playgroud)
我尝试了很多,发现NpgsqlDataAdapter有列代码问题.当我忽略它然后它工作.列代码的DataType是varchar.我不知道为什么会这样.有人有想法吗?
这是因为默认DataAdapter
使用Optimistic Concurrency
.这意味着,如果您尝试更新数据库中不再存在或更改的行,则更新DataAdapter
将失败,并显示上述异常.
可能的情况:
例如:
DataTable
将用于更新的内容.Code = 1101
直接从数据库中删除(例如)行,即您不使用DataTable
此处.这是模拟另一个用户Code = 1101
从另一个应用程序中删除该行.或者代码中的其他部分删除行Code = 1101
.Code = 1101
从中选择出行DataTable
,这只是为了表明它仍然存在,即使您已从数据库本身删除它.Quantity
的行与列Code = 1101
中DataTable
.必须这样做,否则对Update的调用将在更新时忽略此行.如果要实现Last Writer Wins
,请添加以下代码:
cb.ConflictOption = ConflictOption.OverwriteChanges;
Run Code Online (Sandbox Code Playgroud)
还有一个可能的事情:如果你在数据库中有Decimal
/ numeric
作为列,即使数据看起来相同,它们也可能导致此错误.这是由于十进制舍入错误.
一个重要的注意事项:你应该总是使用parameterized queries
顺便说一句.这种字符串连接是开放的SQL Injection
.
归档时间: |
|
查看次数: |
1207 次 |
最近记录: |