实体框架数据库首先:时间戳列不起作用

Ali*_*eza 5 concurrency timestamp entity-framework-5

使用db first方法,我希望我的应用程序在我尝试更新(过时的)实体时抛出并发异常,该实体已经由另一个应用程序/用户/会话更新了数据库中的相应行.

我在.Net 4.5上使用Entity Framework 5.相应的表具有Timestamp列以维护行版本.

Ali*_*cia 11

我在过去通过向要执行并发检查的表添加时间戳字段来完成此操作.(在我的例子中,我添加了一个名为ConcurrencyCheck的列)

根据您的需要,这里有两种类型的并发模式:

1并发模式:已修复:

然后在模型中重新添加/刷新表格.对于固定并发,请确保在将其导入模型时将表的并发模式设置为固定:如下所示:

在此输入图像描述

然后陷阱这个:

    try 

    { 

    context.SaveChanges(); 

    } 

    catch (OptimisticConcurrencyException ex) { 


////handle your exception here...
Run Code Online (Sandbox Code Playgroud)

2.并发模式:无

如果您希望处理自己的并发检查,即提出通知用户的验证,甚至不允许进行保存,那么您可以设置并发模式无.

1.确保将刚添加的新列的属性中的ConcurrencyMode更改为"None". 2.要在代码中使用它,我会创建一个变量来将当前时间戳存储在要检查保存的屏幕上.

private byte[] CurrentRecordTimestamp 
        { 
            get 
            { 
                return (byte[])Session["currentRecordTimestamp"]; 
            } 

            set 
            { 
                Session["currentRecordTimestamp"] = value; 

            } 
        }
Run Code Online (Sandbox Code Playgroud)

1.在页面加载(假设您使用的是asp.net而不是mvc/razor,上面没有提到),或者当您使用希望编辑的数据填充屏幕时,我会在编辑的ConcurrencyCheck值下拉出当前记录进入你创建的这个变量.

 this.CurrentRecordTimestamp = currentAccount.ConcurrencyCheck;
Run Code Online (Sandbox Code Playgroud)

然后,如果用户将记录保持打开状态,同时其他人更改记录,然后他们也尝试保存,则可以将之前保存的时间戳值与现在的并发值进行比较.

if (Convert.ToBase64String(accountDetails.ConcurrencyCheck) != Convert.ToBase64String(this.CurrentRecordTimestamp)) 
{ 
} 
Run Code Online (Sandbox Code Playgroud)

  • **这个解决方法是我已经在我自己的答案中指出的。**它的缺点是,每当重新创建 .edmx 文件时,修改都会以静默方式丢失。 (2认同)

Ali*_*eza 5

在回顾了这里和网上解释实体框架5中的并发性和时间戳的许多帖子之后,我得出的结论是,当从现有数据库生成模型时,基本上不可能获得并发异常.

一种解决方法是修改.edmx文件中生成的实体,并将实体的timestamp属性的"Concurrency Mode"设置为"Fixed".不幸的是,如果从数据库重复生成模型,则此修改可能会丢失.

但是,有一个棘手的解决方法:

  1. 使用可重复读取或更高的隔离级别初始化事务范围

  2. 获取行的时间戳

  3. 将新时间戳与旧时间戳进行比较

  4. 不相等 - >例外

  5. Equal - >提交交易

隔离级别对于防止推断的并发修改很重要.

PS: Erikset的解决方案似乎可以克服重新生成模型文件.

  • 我对这个问题的回答:http://stackoverflow.com/questions/11980516/automating-concurrencymode-set-to-fix-in-edmx提供了一个控制台应用程序,可以自动执行查找时间戳属性和设置并发模式的过程.你的edmx文件.您可以将其作为预构建步骤运行以自动执行该过程. (2认同)
  • 谢谢你的建议.我们已经有一个日期修改日期时间列.所以我在该专栏中应用了这个答案中建议的5个步骤.虽然datetime列方法没有bug和干净,但我们不想修改edmx.令人遗憾的是,即使在4年后,也没有简单的办法. (2认同)