1、使用TableAdapter.Update的时候如何只更新“已修改的”列值,而不是整行提交,累似linq to sql的SubmitChanges一样。
2、当遇到并发的时候,如何以合并的方式来处理结果而不是覆盖,就像如下linq to sql代码实现的一样:
try
{
dc.SubmitChanges(ConflictMode.ContinueOnConflict);
}
catch (ChangeConflictException)
{
foreach (ObjectChangeConflict occ in dc.ChangeConflicts)
{
//保留数据库中的值和当前值,进行合并处理
occ.Resolve(RefreshMode.KeepChanges);
}
}
dc.SubmitChanges(ConflictMode.FailOnFirstConflict);
对于1,你可以自己写代码来控制,本身的Update是没有这样的功能的。参考链接:http://msdn.microsoft.com/en-us/library/ms233819(VS.80).aspx
对于2,我只能说你这个要求太高了。就没见过并发是这样干的...,不过如果你想实现这种效果,可以采取以下方式:
比如有表A,包含字段Id,C1,C2,C3,如果我修改了C1,C2,那么发送两条sql语句
update A set C1=newValue where Id='id' and C1='oldValue'
update A set C2=newValue where Id='id' and C2='oldValue'
这样的话能达到简单合并的效果(以第一次更改为准,后面的更改不覆盖第一次变更)。
谢谢你的回复,我想再请教一下!
当遇到并发的时候你是怎样做的?比如有表A,包含字段Id,C1,C2,C3,如果“用户1”和“用户2“同时读取了表A,然后用户2修改了C1、C2并update,当“用户1"修改了C1、C2然后update的时候就会产生并发,这时一般是如何处理的?谢谢!(是否先提示用户,然后整行覆盖吗)
@jingjing2012: 这个时候,要看需求是如何的了。一般情况下,直接后者覆盖。
如果需要处理的话,一般是通过时间戳的方式。在获取数据的时候拿到时间戳,在提交更新的时候update table set xx =xx where id= '' and 时间戳='xxx',这样的话,如果在更新之前已经有过更新,那么本次更新就会实现,实现了冲突检测。
学习
想问下楼主,你这样真可以解决冲突吗?
try { dc.SubmitChanges(ConflictMode.ContinueOnConflict); } catch (ChangeConflictException) { foreach (ObjectChangeConflict occ in dc.ChangeConflicts) { //保留数据库中的值和当前值,进行合并处理 occ.Resolve(RefreshMode.KeepChanges); } } dc.SubmitChanges(ConflictMode.FailOnFirstConflict);
这个问题我一直认为是程序无解的,因为逻辑错误解决不了。
解决不了,但是你不觉得这样更合理吗?后来者用“修改"的数据去覆盖前者数据,而不是整条记录覆盖。
@jingjing2012:
如果要讨论合理性的话,我目前采用的方式是,只要有人修改过,后保存的不允许保存。
也就是说,你必须知道你想保存的数据被人修改过了。
@jingjing2012: 我想说一点,对于【后来者用“修改"的数据去覆盖前者数据,而不是整条记录覆盖。】这个看似合理的方案,其实并不合理。会对用户造成很大的疑惑,为什么数据会部分被更新(实际是先后两人操作的组合结果)?一般最常用的做法就如 @爱编程的大叔 所说,后保存的如果发现数据已变更,那么不允许保存。