none
关于并发冲突时覆盖数据库值的疑惑(LINQ to SQL) RRS feed

  • 问题

  • 根据MSDN文档的说法啊,使用LINQ to SQL遇到并发冲突的时候,至少有三种可选的解决办法,其中一个就是使用用户修改的数值覆盖数据库当前的值。这可通过ObjectChangeConflict.Resolve(RefreshMode.KeepCurrentValues)来实现。可参看下面附上的完整测试代码。然而,我再测试中得出的结论是这样的:并发冲突确实发生了,但并没有用用户当前的值替换数据库中的值。

    NorthwindDataContext dba = new NorthwindDataContext(@"C:\LINQ\Northwind.mdf");
    NorthwindDataContext dbb = new NorthwindDataContext(@"C:\LINQ\Northwind.mdf");
    
    try
    {
      // 模拟用户A和用户B同时获取相同编号的产品记录。
      var ProductA = dba.Products.First(P => P.ProductID == 1);
      var ProductB = dbb.Products.First(P => P.ProductID == 1);
    
      // 用户B首先修改数据。
      ProductB.UnitPrice = ProductB.UnitPrice + 1;
      dbb.SubmitChanges();
    
      // 用户A在用户B之后修改数据,并试图更新到数据库。
      ProductA.UnitPrice = ProductA.UnitPrice - 1;
      dba.SubmitChanges();
    }
    catch (ChangeConflictException ex)
    {
      Console.WriteLine(ex.Message);
      foreach (ObjectChangeConflict occ in dba.ChangeConflicts)
      {
        // 覆盖数据库中的值,即将更新的数值保存到数据库。
        occ.Resolve(RefreshMode.KeepCurrentValues);
      }
    }
    


    以上面的代码为例,用户B成功更新了数据,而用户A更新的时候,引发了并发冲突。
    此时,所指定的并发冲突的解决办法是KeepCurrentValues,也即覆盖数据库当前的值。
    如果成功被执行的话,应该是这样的:用户A修改后的值将会替换用户B所修改的值。
    然而,事实确实:用户A的数据并没有被更新,数据库中一直保留的是用户B的数值。
    我通过观察所生成的SQL命令发现:似乎在引发并发冲突之后,并没有像数据库提交UPDATE的SQL语句?
    请问这是怎么回事呢?莫非是我的代码编写有误?

    2010年9月20日 3:27

答案

  • KeepCurrentValues Forces the Refresh method to swap the original value with the values retrieved from the database. No current value is modified.
      KeepChanges Forces the Refresh method to keep the current value that has been changed, but updates the other values with the database values.
      OverwriteCurrentValues Forces the Refresh method to override all the current values with the values from the database.
    KeepCurrentValues Forces the Refresh method to swap the original value with the values retrieved from the database. No current value is modified.
      KeepChanges Forces the Refresh method to keep the current value that has been changed, but updates the other values with the database values.
      OverwriteCurrentValues Forces the Refresh method to override all the current values with the values from the database.

    KeepCurrentValues

     Forces the Refresh method to swap the original value with the values retrieved from the database. No current value is modified.
    强制刷新方法 用数据库的值替换(实体)的原始值。(实体)的当前值不做修改。

     

    KeepChanges

    Forces the Refresh method to keep the current value that has been changed, but updates the other values with the database values.

    强制刷新方法 保留(实体)当前已经被修改(产生冲突)的值,但是用数据库的数据覆盖其他字段。

     


     OverwriteCurrentValues

    Forces the Refresh method to override all the current values with the values from the database.

    强制刷新方法 把实体的所有的当前值 用数据库的值覆盖

     

     

     

     

    这里没有提到把数据库覆盖的事情,

    是不是需要在 Resolve 之后  还要调用savechanges  一次呢?

     


    入了ipad,最近用ipad上论坛
    • 已标记为答案 Mog Liang 2010年9月27日 9:52
    2010年9月20日 10:24

全部回复

  • 你好像误会了keep current value 的意思?
    入了ipad,最近用ipad上论坛
    2010年9月20日 5:02
  • 呵呵,如果单看这几个英文单词的话,我也会很自然的联想到保留数据库的值,可事实上并非如此。
    真正保留数据库值的枚举值是OverwriteCurrentValues,我的理解是,这个Current Values指的是实体类对象当前的列属性值,如果Keep的话,自然就应该修改数据库中的值。那如果要是被Overwrite了,当然也就意味着保留数据库中的值了。另外,这个意思,也并非我如此猜测,而是微软的文档就是这么说的!

    2010年9月20日 5:19
  • 也就是说Keep的是实体类对象的CurrentValues,而不是数据库中的CurrentValues。
    2010年9月20日 5:25
  • KeepCurrentValues Forces the Refresh method to swap the original value with the values retrieved from the database. No current value is modified.
      KeepChanges Forces the Refresh method to keep the current value that has been changed, but updates the other values with the database values.
      OverwriteCurrentValues Forces the Refresh method to override all the current values with the values from the database.
    KeepCurrentValues Forces the Refresh method to swap the original value with the values retrieved from the database. No current value is modified.
      KeepChanges Forces the Refresh method to keep the current value that has been changed, but updates the other values with the database values.
      OverwriteCurrentValues Forces the Refresh method to override all the current values with the values from the database.

    KeepCurrentValues

     Forces the Refresh method to swap the original value with the values retrieved from the database. No current value is modified.
    强制刷新方法 用数据库的值替换(实体)的原始值。(实体)的当前值不做修改。

     

    KeepChanges

    Forces the Refresh method to keep the current value that has been changed, but updates the other values with the database values.

    强制刷新方法 保留(实体)当前已经被修改(产生冲突)的值,但是用数据库的数据覆盖其他字段。

     


     OverwriteCurrentValues

    Forces the Refresh method to override all the current values with the values from the database.

    强制刷新方法 把实体的所有的当前值 用数据库的值覆盖

     

     

     

     

    这里没有提到把数据库覆盖的事情,

    是不是需要在 Resolve 之后  还要调用savechanges  一次呢?

     


    入了ipad,最近用ipad上论坛
    • 已标记为答案 Mog Liang 2010年9月27日 9:52
    2010年9月20日 10:24