`
jackchen0227
  • 浏览: 143689 次
  • 性别: Icon_minigender_1
  • 来自: 帝都
社区版块
存档分类
最新评论

ChangeConflictException: Row not found or changed

阅读更多

 

    今天做一个datagrid,数据源是asp:ObjectDataSource。做datagrid的删除按钮的时候,总是提示出现ChangeConflictException: Row not found or changed。单步跟踪的时候,发现别的执行都是正常的,就是在SubmitChanges(),提示出错,参考下文解决问题

前段时间工作中的一个新需求,有机会用到了Linq to SQL。使用后的第一感觉,就是方便很多,也为整个项目节约了一大把的开发时间,甚至代码量也少了很多。不过在程序的实际运行中,始终会遇到一些莫名其妙的异常,最令人不解的,就是“System.Data.Linq.ChangeConflictException: Row not found or changed.” 。当初凭自己和同事的判断,可能是数据库的数据异常所导致,后来发觉这个异常出现得越来越频繁,于是上MSDN查了查,原来是Linq中一个常见的问题:更新冲突。
   这个词说起来比较玄乎,其实再平常不过了。下面可以通过一个简单的例子,来重现这个异常。
   建立一个普通的测试表:LinqTest(如图)

  

     在测试表中,插入一条测试数据(如图)

    

     测试代码如下:

  
 程序代码

namespace LinqTest
{
    class Program
    {
        static void Main(string[] args)
        {
            
            TestDataContext db = new TestDataContext();

            db.Log = Console.Out;
            var result = from p in db.LinqTests
                         where p.ID == 1
                         select p;

            var info = result.FirstOrDefault();
            
            if(info != null)     //插入断点
            {
                info.Age = 25;
                db.SubmitChanges();
            }

            Console.ReadLine();

        }

    }

}
 
    


    在测试代码中,将DataContext的日志定向到Console的输出部分,这样方便我们观察Linq实际执行的SQL语句是什么。重现的时候,我们需要在注释的地方,插入断点进行测试。对于示例中的代码,在正常情况下,是不会有错误的。执行过后,我们可以在Console的输出中,看到实际执行的SQL语句(如图)



   再进行第二次调试,首先,恢复Age的数据到以前的样子。下面我们运行到断点处,然后偷偷去SQL Server Management Studio中,手动修改数据,将原始数据中的Age,由24,改为22。然后回到VS2008的IDE,按F5继续运行程序,这个时候,你会发现异常出现了(如图)



    再回到Console的输出,查看,执行的SQL语句和刚才的一样。这就是问题的所在,在正常运行状态下,Linq在运行时,会把数据库的数据缓存到实体对象中,这是一种理想化的情况,并且在更新时,Linq会默认把除更新字段外的所有字段,作为Update语句中的Where条件。但是,如果此时有另外的程序,在访问数据库,并修改数据库数据的时候,比如刚才把Age改为22。此时Linq缓存起来的数据和实际数据库中的数据产生了不一致的情况。Linq此时仍然把被修改过的字段,作为Update的Where条件,但是数据库中Age早就被我们改过了,不再是25,Where条件始终匹配不到原有的数据。这时,就会抛出所谓的:“System.Data.Linq.ChangeConflictException: Row not found or changed.”异常。

    产生此异常,主要是Linq缓存数据和实际数据库数据不一致的情况造成。解决次问题的情况,主要有几种:

    1.比较简单的方法,不使用Linq提供的SubmitChanges()方式提交更改,而直接执行SQL语句,例如:
     db.ExecuteCommand("Update [dbo].[LinqTest] SET Age=25 Where ID = @p0", 1);
    这样虽然比较方便,但是感觉又回到了直接写SQL的时代,毕竟Linq to SQL的目的,就是为了让我们看不见SQL,避免写复杂的SQL语句,而直接操作实体对象,这样也可以避免程序可读性差、不便于维护。所以除非万不得已,还是不太推荐使用此方法。

    2.参考MSDN的资料,采用Linq提供的解决更新冲突的方法,在异常中捕获冲突,然后手动解决冲突:
 程序代码
  
try
{
    db.SubmitChanges(System.Data.Linq.ConflictMode.ContinueOnConflict);
}
catch (System.Data.Linq.ChangeConflictException ex)
{
    foreach (System.Data.Linq.ObjectChangeConflict occ in db.ChangeConflicts)
    {
         //以下是解决冲突的三种方法,选一种即可

        // 使用当前数据库中的值,覆盖Linq缓存中实体对象的值
        occ.Resolve(System.Data.Linq.RefreshMode.OverwriteCurrentValues);
        
        // 使用Linq缓存中实体对象的值,覆盖当前数据库中的值
        occ.Resolve(System.Data.Linq.RefreshMode.KeepCurrentValues);
        
        // 只更新实体对象中改变的字段的值,其他的保留不变
        occ.Resolve(System.Data.Linq.RefreshMode.KeepChanges);
    }

    // 这个地方要注意,Catch方法中,我们前面只是指明了怎样来解决冲突,这个地方还需要再次提交更新,这样的话,值   
 //才会提交到数据库。
    db.SubmitChanges();
}
 


    3. 这个方法也比较简单,也即MSDN中所说的Pessimistic Concurrency Control  。 我们可以来设定哪些字段需要放入Where条件,哪些字段不需要,这样就可以控制更新时候的条件匹配尺度。具体做法,就是在Linq to SQL Designer中,把一些字段的UpdateCheck属性设置为Never,这样,这些字段在更新的时候,就不会再出现在Where条件中了。其实比较推荐的做法,就是在表中设立主键,因为更新的时候,只要把主键作为Where条件,就可以单独的确立一行数据了。把除主键外的字段属性中UpdateCheck设置为Never即可。
分享到:
评论

相关推荐

    端午送祝福语小程序源码(可对接流量主)

    该小程序的作用就是祝福语生成距离端午节也不远了,可以抓住机会蹭一波流量用户可以点击直接发送祝福语给好友 分享的时候会显示用。

    基于Springboot微服务的车联网位置信息管理软件的设计与实现+论文

    基于Spring Boot微服务的车联网位置信息管理软件旨在通过现代化技术提升车辆位置信息的实时监控与管理效率。以下是该系统的功能模块和技术实现的简要介绍: 系统功能模块 车辆定位与追踪:通过集成GPS等定位技术,实时获取车辆位置信息,并提供车辆追踪功能。 位置信息管理:存储、查询、更新车辆位置信息,支持历史轨迹回放和位置数据统计分析。 报警与预警:根据预设规则,对异常位置信息进行报警和预警,如超速、越界等。 用户管理:支持用户注册、登录、权限管理等操作,确保系统安全和数据保密。 技术实现 后端技术:采用Spring Boot框架构建微服务架构,利用Maven进行项目管理,确保系统的高性能和稳定性。 数据库:使用MySQL数据库存储车辆位置信息、用户数据等关键信息,支持高效的数据查询和统计分析。 定位技术:集成GPS等定位技术,实现车辆位置的实时获取和追踪。 前端技术:结合Vue.js等前端框架,构建直观、友好的用户界面,提供丰富的交互体验。 该系统通过Spring Boot微服务架构和现代化技术,实现了车联网位置信息的实时监控与管理,为车辆管理提供了有力的技术支持。

    毕业设计MATLAB_SIFT特征提取.zip

    毕业设计MATLAB_SIFT特征提取.zip

    微信小程序-城市天气2小程序项目源码-原生开发框架-含效果截图示例.zip

    微信小程序凭借其独特的优势,在移动应用市场中占据了一席之地。首先,微信小程序无需下载安装,用户通过微信即可直接使用,极大地降低了使用门槛。其次,小程序拥有与原生应用相近的用户体验,同时加载速度快,响应迅速,保证了良好的使用感受。此外,微信小程序还提供了丰富的API接口,支持开发者轻松接入微信支付、用户授权等功能,为开发者提供了更多的可能性。 微信小程序-项目源码-原生开发框架。想要快速打造爆款小程序吗?这里有一份原生开发框架的项目源码等你来探索!基于微信小程序的强大生态,这份源码将带你领略原生开发的魅力,实现快速迭代与高效开发。从用户授权到微信支付,从界面设计到功能实现,一切尽在掌握。赶快下载查看,让你的小程序项目在竞争激烈的市场中脱颖而出!

    医师定期考核工作安排表.docx

    医师定期考核工作安排表.docx

    yolo学习导航.txt

    yolov10

    Golang_Go100个错误和如何避免它们.zip

    Golang_Go100个错误和如何避免它们

    京麒CTF2024-Re-easy-wasm(wasm逆向分析)

    京麒CTF2024-Re-easy-wasm(wasm逆向分析)

    基于Springboot+Vue的米家商城的设计与实现+论文

    基于Spring Boot和Vue的米家商城设计与实现,系统致力于提供用户一个便捷、多样化的购物体验。以下是系统功能模块和技术实现的简要介绍: 系统功能模块 用户模块: 注册登录:支持用户快速注册和登录。 个人中心:展示用户信息、订单记录、地址管理等。 购物车:管理用户选中的商品,支持结算和修改。 商品模块: 商品展示:按分类或搜索展示商品详情。 商品详情:展示商品详细信息,包括价格、评价等。 购物车加入:用户可将商品加入购物车。 订单模块: 订单生成:用户提交订单,系统生成订单信息。 订单查询:用户可查询自己的订单状态。 订单支付:支持多种支付方式,确保交易安全。 管理员模块: 商品管理:添加、编辑、删除商品信息。 用户管理:查看、编辑用户信息,管理用户权限。 订单管理:查看、处理用户订单。 技术实现 后端:采用Spring Boot框架,基于Java语言开发,提供RESTful API接口,确保系统的高性能和稳定性。 前端:使用Vue.js框架构建用户界面,通过Axios与后端进行通信,实现数据交互和展示。 数据库:采用MySQL数据库存储商品、用户、订单等关键数据。 开发工具:

    Golang_Gogithuubs在线模式迁移工具MySQL.zip

    Golang_Gogithuubs在线模式迁移工具MySQL

    类型转换之显式转换习题及参考答案

    类型转换之显式转换习题及参考答案

    libaa-devel-1.4.0-0.rc5.34.mga8.armv7hl.rpm

    安装:rpm -i xx.rpm

    音乐播放器带后端.zip

    小程序开发案例

    微信小程序-Railay:整体框架小程序项目源码-原生开发框架-含效果截图示例.zip

    微信小程序凭借其独特的优势,在移动应用市场中占据了一席之地。首先,微信小程序无需下载安装,用户通过微信即可直接使用,极大地降低了使用门槛。其次,小程序拥有与原生应用相近的用户体验,同时加载速度快,响应迅速,保证了良好的使用感受。此外,微信小程序还提供了丰富的API接口,支持开发者轻松接入微信支付、用户授权等功能,为开发者提供了更多的可能性。 微信小程序-项目源码-原生开发框架。想要快速打造爆款小程序吗?这里有一份原生开发框架的项目源码等你来探索!基于微信小程序的强大生态,这份源码将带你领略原生开发的魅力,实现快速迭代与高效开发。从用户授权到微信支付,从界面设计到功能实现,一切尽在掌握。赶快下载查看,让你的小程序项目在竞争激烈的市场中脱颖而出!

    C语言课程设计(成绩管理系统)源程序

    C语言课程设计(成绩管理系统)源程序

    剪辑必备AE红色粒子Banner背景-480P 清晰-AVC.mp4

    这是一个为视频编辑和动画制作者设计的动态背景素材。 它采用了先进的Adobe After Effects(简称AE)技术,创造出一个充满活力和视觉冲击力的红色粒子效果。 适用于制作各种视频内容的背景,如广告、宣传片、社交媒体视频等。 视频以480P的清晰度呈现,确保了即使在较低分辨率的播放设备上也能保持画面的清晰度和细节。采用AVC(Advanced Video Coding)编码格式,这是一种高效的视频压缩技术,能够在保持画质的同时,减少文件的大小,便于存储和传输。 红色粒子的动态效果,如同烟花绽放,又似星河流动,充满了动感和现代感。粒子在屏幕上自由地飘散、聚集,形成各种美丽的图案和形状,为视频增添了无限的想象空间和创意表现力。这种粒子效果可以很好地吸引观众的注意力,同时也为视频内容提供了一个完美的视觉框架。 无论是用于商业宣传,还是个人视频创作,这个红色粒子Banner背景都能够提升视频的专业感和吸引力。它易于编辑和定制,用户可以根据自己的需求调整粒子的颜色、速度、密度等参数,创造出独一无二的视觉效果。总之,这是一个多功能、高效率的视频背景资源,值得每一位视频制作者拥有。

    Dev-cpp软件压缩包

    Dev-cpp软件压缩包供大家下载!

    Golang_Gogitlfs自定义传输适配器,它简单地使用一个文件夹作为远程LFS媒体存储,例如共享NAS文件夹.zip

    Golang_Gogitlfs自定义传输适配器,它简单地使用一个文件夹作为远程LFS媒体存储,例如共享NAS文件夹

    2023 高级软件测试开发工程师全套视频.zip

    资源目录:2023 高级软件测试开发工程师,本课程共77.26G ├──测试开发 | ├──21–前端技术之JQuery NO.69 | | ├──课件资料 | | ├──章节1 JavaScript基础入门 | | ├──章节2 流程控制语句 | | ├──章节3 Function 函数 | | ├──章节4 正则表达式 | | ├──章节5 DOM操作 | | ├──章节6 jQuery应用实践 | | └──章节7 jQuery源码分析 | ├──Flask框架NO.145 | | ├──1,虚拟化环境 | | ├──2,视图和URL | | ├──3,Jinjia2模板 | | ├──4,Flask高级1 | | ├──5,Flask数据库和ORM框架 | | └──6,Flask-restful | ├──MongoDB基础入门到企业级应用(官网未更新) | ├──MySQL与Python的交互-981 | | └──章节1-MySQL与Python的交互 | ├──PyQt桌面工具开发(官网未更新) | ├──Redis_高效的NoSQL数据库-32 | | ├──章节1-

    notebook-6.5.0a0.tar.gz

    Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。

Global site tag (gtag.js) - Google Analytics