1.首先 解释一下我们保存数据操作 UpdateDataSet(ds)
oracle公司提供的类库Oracle.DataAccess.dll
或者是 微软提供的类库System.Data.dll
要将修改过的DataSet保存到数据库 要有一些约定
a. 表明必须和真实数据库中的一致
data.Tables[0].TableName = "table3"
b. 必须将主键查询出来
string cmdText = "select id,name,content from table3";//id是主键
c. 数据行 状态为Modify或Added 才会被保存
d. 只有真实的列名的列 将被保存到数据库 别名的列不会被保存
2.并发冲突怎么产生的
一个DataRow的状态为Modify的时候
原始值 row["ColumnName",DataRowVersion.Original]
新值 row["ColumnName",DataRowVersion.Current]
使用Oracle.DataAccess.dll类库提交保存的时候
比较 "数据库中" 这一行的数据 和 原始值 是否相同;
如果不同会抛出 "并发冲突"
(常见情况 我们将数据取到DataSet后,其他人修改了这行数据)
如果相同就正常保存
微软的类库不会有此类问题
3.出现并发冲突 我们优先保存后修改的值
我们在基类里面处理了并发问题
4.代码错误 造成 不应该产生的并发冲突的数据行 产生"并发冲突"
a.我们新开一个页面的时候 DataSet从数据库取值
"select id,name,count from table3" id=1,
name=DBNull,count=1
b.我们在页面上将count修改成11
c.收集类 收集界面的值 id=1,
name="",count=11
d.将收集类的值 赋值给 DataRow
各页面都有类似的 ***UIToDataRow(obj,
dataRow) 这个方法
if (obj.name== null )
{
dataRow["name"] = DBNull.Value;
}
else
{
dataRow["name"] = obj.name.ToString(); //空字串 所以这句将被执行到
}
{
dataRow["name"] = DBNull.Value;
}
else
{
dataRow["name"] = obj.name.ToString(); //空字串 所以这句将被执行到
}
这时数据 DataSet中 原始值 id=1,
name=DBNull,count=1 新值 id=1,
name="",count=11
e.我们提交保存 可以正常保存到数据库
(注意name="" 保存到oracle数据库 就是DBNull)
f.保存成功后 DataSet 会AcceptChanges
这时数据 DataSet中 原始值 id=1,
name="",count=11
g.界面再次修改count=22 过程类似
h.提交保存 这时数据 DataSet中 原始值 id=1,
name="",count=11 新值 id=1,
name="",count=22
这时原始值的name
="" 和 数据库的 name=DBNull 不相同 发生并发冲突
5.可能的解决方案
a.在***UIToDataRow() 这个方法中修改赋值代码为
if (string.IsNullOrEmpry(obj.name) )
{
dataRow["name"] = DBNull.Value; //空字串 将执行这个
}
else
{
dataRow["name"] = obj.name.ToString();
{
dataRow["name"] = DBNull.Value; //空字串 将执行这个
}
else
{
dataRow["name"] = obj.name.ToString();
}
b.修改客户端JS代码 将空字串收集成 null
这样修改对oracle没有问题 对sqlserver可能产生问题 试验中...