• 使用Linq 更新数据库时遇到的一些问题及解决办法


    刚开始使用Linq,对linq 的更新策略还不是很了解,所以在设计数据库的时候根本就没有考虑到更新检查策略。在插入的时候没有任何问题,更新数据的时候,问题就来了,报错:“System.Data.Linq.ChangeConflictException: Row not found or changed”(找不到行或行已更改)。在网上查了下,这个问题有两种解决办法:一是增加 timestamp(时间戳)列,二是设置主键 IsVersion="true"。我选用了第二种解决办法,OK,更新数据库没有问题了。但是,插入的时候报错:“主键不能插入NULL值”,设置断点,单步跟踪,直到 SubmitChanges()之前,都是有值的,执行SubmitChanges()方法,就报上面的错误。无奈,我决定使用第二种解决办法:设置timestamp列,OK,插入和更新都不报错了。

    下面我来简单说一下Linq的更新检查策略。

    在正常运行状态下,Linq在运行时,会把数据库的数据缓存到实体对象中,所以我们更新数据的时候,并不是直接更新数据库,而是更新缓存中的数据,然后将更改提交到数据库。Linq采用了一种叫做“乐观式并发”的策略。乐观式并发允许任意多的用户随时修改他们自己的一份数据的拷贝。在提交修改时,程序将检查以前的数据是否有所改变。若没有变化,则程序只需保存修改即可。若发生了变化并存在冲突,那么程序将根据实际情况决定是将前一修改覆盖掉,还是把这一次新的修改丢弃,或是尝试合并两次修改。乐观式并发的前一半操作相对来说比较简单。在不需要并发检查的情况下,数据库中使用的SQL语句将类似于如下语法:UPDATE TABLE SET [field = value] WHERE [Id = value]。不过在乐观式并发中,Where子句将不只包含ID列,同时还要比较表中其他各列是否与原有值相同,Linq会默认把除更新字段外的所有字段,作为Update语句中的Where条件。 在调用DataContext的SubmitChanges方法时,LINQ将生成上述Update语句并发送给数据库处理。若这条语句并没有更新数据库中的任意一行,那么DataContext就得知更新过程中产生了冲突,于是抛出“找不到行或行已更改”异常。实际使用中,若用来实现乐观式并发的参数数量过多,可能会导致一些性能上的问题。在这种情况下,我们可以借助UpdateCheck来修改映射规则,只让对象中的一部分属性参与到乐观式并发检查中。在默认情况下,属性的UpdateCheck将设置为Always,即表示LINQ to SQL将用该属性检查乐观式并发。我们可以根据需要将其调整为只在该属性值发生改变时才检查(WhenChanged),或是从不使用该属性进行检查(Never)。

    若在数据表中有timestamp 列,其它列(主键除外)的UpdateCheck属性会默认设置为Never,若使用IsVersion作为更新检查依据,则必须在字段上手动设置UpdateCheck.Never属性来避免更新检查,但是如果数据表更新、新增存储过程,需要重新生成dbml的话,你在字段上设置的IsVersion和UpdateCheck.Never都将消失不见,你需要手动重新设置一遍,真是烦不胜烦,所以我推荐使用timestamp作为更新检查依据。

    (转自 http://blog.csdn.net/zhangyumei/archive/2010/04/25/5526873.aspx

  • 相关阅读:
    JAVA 解压压缩包中指定文件或实现压缩文件的预览及下载单个或多个指定的文件
    java 解压zip java.lang.IllegalArgumentException: MALFORMED 错误
    Java文件管理系统
    Java实现用汉明距离进行图片相似度检测的
    url 编码(percentcode 百分号编码)
    nodejs进程管理
    nodejs网络编程
    nodejs内存溢出 FATAL ERROR: CALL_AND_RETRY_0 Allocation failed – process out of memory
    connect ECONNREFUSED 127.0.0.1:80错误解决
    nuxtjs如何在单独的js文件中引入store和router
  • 原文地址:https://www.cnblogs.com/AndyGe/p/1747294.html
Copyright © 2020-2023  润新知