当前位置: 首页 > news >正文

在LINQ to SQL中处理“更新已被其它用户删除对象”的错误

在LINQ to SQL中处理“更新已被其它用户删除对象”的错误

在多用户条件下,当你正在修改一条记录时,很有可能另一个用户已把此记录删除。这时,等你修改完毕向数据库提交请求时,会出现“更新已被其它用户删除对象”的错误。

在LINQ to SQL中,所有本次数据更改冲突都被记录到DataContext.ChangeConflicts集合中。

通过遍历这个集合,可以知道引发冲突的原因。

多用户条件下引发数据更改冲突的原因主要有两种:

1更新已被其它用户更新的对象

2更新已被其它用户删除的对象

对于上述两种状况,LINQ to SQL采取了不同的处理方法。

对于第1种情况,LINQ to SQL的DataContext.ChangeConflicts集合对象提供了一个“ResolveAll(更新模式)”方法,最常用的是以下这个形式:

        //数据更新冲突时,将我的值与其他用户提交的值合并,但我修改过的值拥有最高优先级

context.ChangeConflicts.ResolveAll(RefreshMode.KeepChanges);

另两种更新冲突处理策略是:

(1) KeepCurrentValues即我的值最优先,不管我改过没有,一律用我的值覆盖对应的数据库值来解决此冲突。

(2)OverwriteCurrentValues 用数据库中的当前值全面取代我现在的值,放弃我做的修改。

选择好合适策略调用ResolveAll()后,再次调用DataContext.SubmitChanges()方法将会成功更新数据库。

对于第2种情况(“更新已被其它用户删除的对象”),LINQ to SQL的处理比较另类:

如果你调用ResolveAll(更新策略)方法,LINQ to SQL仅是简单地将与此对应的冲突对象(ObjectChangeConflict类型)的IsResolve属性设置为True,其结果是LINQ to SQL将不再尝试更新此对象!


换句话说:你调用ResolveAll(更新策略)方法后,LINQ to SQL认为你不打算处理这个已被其它用户删除的对象,就将其打入“冷宫”,不再理会。

现在有一个问题:

如果我想当“更新已被其它用户删除的对象”这一现象出现时,重新向数据库插入此对象,怎么办?

除非采用序列化方法,否则LINQ to SQL不允许将一个实体对象分离出来。但我们可以克隆一个新对象再将其插入到Table<entity>中。然后,将“更新已被其它用户删除的对象”对应的冲突对象设置为“已解决”状态。

以下代码片断来自于一个Windows Form应用程序:

     try
{
context.SubmitChanges(ConflictMode.ContinueOnConflict);
}
catch (ChangeConflictException)
{
foreach (ObjectChangeConflict occ in context.ChangeConflicts)
{
//如果其它用户已删除此实体对象对应的数据库记录

if (occ.IsDeleted)
{

         //克隆一个新实体对象
Book newbook = CloneBook(book);
//下次提交时,将插入新对象到Book表中
context.Book.InsertOnSubmit(newbook);
//通知DataContext不再处理此已被其他用户删除数据库记录的实体对象
occ.Resolve();
}

}

//普通的更新冲突,则将我的值与其他用户提交的值合并以解决冲突

context.ChangeConflicts.ResolveAll(RefreshMode.KeepChanges);
//再次提交
context.SubmitChanges(ConflictMode.FailOnFirstConflict);

}
catch (Exception ex)
{

MessageBox.Show(ex.Message, "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Error);

}

上述模板代码中,context代表DataContext对象,Book是数据库中的表,LINQ to SQL会为它生成同名的实体类。

使用LINQ to SQL更新数据库需要有几个注意事项:

1 当数据表间有主键外键关联时,注意在数据库中将这个关联关系设置为层叠更新与删除。否则, SQL Server会阻止你删除主表记录。除非你一条条地将从表相关记录删除干净后才能删除主表记录。

对应地,如果你要删除某LINQ to SQL实体类对象,但这个对象还包容着相关联的子实体类对象时,一旦尝试向数据库提交更改,而数据库中没有将这个关联关系设置为层叠更新与删除,则LINQ to SQL将自动回滚操作,一条记录也删除不了!其原因是DataContext.SubmitChange()方法默认启动了一个事务,一出现异常则自动回滚。

2 克隆有主键外键关联的实体对象时,注意要一并克隆其所包容的子对象,而不要简单地赋值,那是“对象引用复制”而非“对象本身数据的复制”。具体来说,就是new一个新对象,然后逐个地把老对象的值赋给新对象,这个过程可能会递归好几层。最简单的方法是将原对象序列化到一个内存流中,然后从内存流中反序列化以实现对象的完全克隆。

3 如果需要获取数据库最新数据,可以调用DataContext.Refresh()方法,或者最简单的,直接向数据库发送一个新的LINQ查询,然后更新界面即可(推荐使用数据绑定),后面这个方法最简单可靠。

多用户环境下数据库的记录的存取冲突是一个令人头痛的问题,需要仔细地处理各种情况,这篇短文期望对大家有点帮助。

由于本人对LINQ to SQL技术研究与应用不深,因此,如本文有错,敬请朋友指出。

相关文章:

  • 算法练习--打印Cantor 数表
  • 企业中的4种人才
  • Sun的启示------技术在企业发展中的分量
  • Computer Science 学习第四章--CPU 指令集及指令处理
  • 领域模型驱动应用心得....
  • 算法练习--除法
  • 移动互联网 3G时代的“新宠”
  • 算法练习--双基回文数
  • C# 格式化显示金额函数
  • [Web开发] IE8的User-Agent 字符串
  • 算法练习--素数环
  • 算法练习--判断连续相同字符串
  • [IE编程] IE8的SDK 下载
  • JS 数组扩展函数--求起始项到终止项和
  • 谷歌音乐搜索模式是个不错的尝试
  • [数据结构]链表的实现在PHP中
  • 【跃迁之路】【444天】程序员高效学习方法论探索系列(实验阶段201-2018.04.25)...
  • 2018以太坊智能合约编程语言solidity的最佳IDEs
  • axios 和 cookie 的那些事
  • css属性的继承、初识值、计算值、当前值、应用值
  • Docker入门(二) - Dockerfile
  • Fabric架构演变之路
  • in typeof instanceof ===这些运算符有什么作用
  • Javascript编码规范
  • Java新版本的开发已正式进入轨道,版本号18.3
  • Linux Process Manage
  • Linux下的乱码问题
  • PHP面试之三:MySQL数据库
  • RxJS: 简单入门
  • TypeScript迭代器
  • Vue UI框架库开发介绍
  • vue2.0一起在懵逼的海洋里越陷越深(四)
  • Work@Alibaba 阿里巴巴的企业应用构建之路
  • 百度地图API标注+时间轴组件
  • 高度不固定时垂直居中
  • 将 Measurements 和 Units 应用到物理学
  • 解析 Webpack中import、require、按需加载的执行过程
  • 嵌入式文件系统
  • 时间复杂度与空间复杂度分析
  • 因为阿里,他们成了“杭漂”
  • 宾利慕尚创始人典藏版国内首秀,2025年前实现全系车型电动化 | 2019上海车展 ...
  • ​一帧图像的Android之旅 :应用的首个绘制请求
  • #define、const、typedef的差别
  • #Linux(Source Insight安装及工程建立)
  • #LLM入门|Prompt#1.8_聊天机器人_Chatbot
  • (3)STL算法之搜索
  • (html5)在移动端input输入搜索项后 输入法下面为什么不想百度那样出现前往? 而我的出现的是换行...
  • (附源码)spring boot北京冬奥会志愿者报名系统 毕业设计 150947
  • (附源码)ssm考试题库管理系统 毕业设计 069043
  • (十八)devops持续集成开发——使用docker安装部署jenkins流水线服务
  • .Net Core webapi RestFul 统一接口数据返回格式
  • .Net Core缓存组件(MemoryCache)源码解析
  • .NET WebClient 类下载部分文件会错误?可能是解压缩的锅
  • .NET 反射的使用
  • .netcore 如何获取系统中所有session_ASP.NET Core如何解决分布式Session一致性问题