实体框架乐观并发异常不存在的 [英] Entity Framework Optimistic Concurrency Exception not occuring

查看:113
本文介绍了实体框架乐观并发异常不存在的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有一个使用EF4作为其数据访问层一个ASP.Net MVC应用程序,我们看到同当我们认为他们应该不会被抛出关于OptimisitcConcurrencyExceptions意外行为。

We have an ASP.Net MVC application that uses EF4 as its data access layer and we're seeing unexpected behaviour with regards to OptimisitcConcurrencyExceptions not being thrown when we think they should be.

我们已经简化了问题倒在以下code ...

We have simplified the problem down to the following code...

   using System.Linq;
    using Project.Model;

    namespace OptimisticConcurrency
    {
        class Program
        {
            static void Main()
            {
                Contact firstContact = null;
                using (var firstEntities = new ProjectEntities())
                {
                    firstContact = (from c in firstEntities.Contacts 
                       where c.LastName == "smith" select c).Single();
                }

                using (var secondEntities = new ProjectEntities())
                {
                    var secondContact = (from c in secondEntities.Contacts 
                       where c.LastName == "smith" select c).Single();

                    secondContact.Title = "a";
                    secondEntities.SaveChanges();
                }

                firstContact.Title = "b";

                using (var thirdEntities = new ProjectEntities())
                {
                    var thirdContact = (from c in thirdEntities.Contacts 
                       where c.LastName == "smith" select c).Single();

                    thirdContact.Title = firstContact.Title;

                    //EXPLICITLY SET VERSION HERE
                    thirdContact.Version = firstContact.Version;  

                    thirdEntities.SaveChanges();
                }
            }
        }
    }

这是在我们的MVC应用程序会发生什么一个相当简单的版本,但出现同样的问题。

This is a rather simple version of what happens in our MVC app, but the same problem occurs.

当我们呼吁thirdEntities的SaveChanges,我期望例外,没有被抛出。

When we call SaveChanges on the thirdEntities, I expect the exception and nothing is being thrown.

更有趣的是,当我们重视的SQL事件探查器中,我们看到的是where子句中正在使用的版本,但它正在被使用,而不是firstEntities值尽管它是thirdEntities版本值(当前在DB)被称为前的SaveChanges明确立即置位。调用SaveChanges被重置版本是检索到的值不是设定值。

Much more interestingly, when we attach the SQL Profiler, we see that the Version is being used in the where clause but it is thirdEntities Version value (the current one in the DB) being used, not the firstEntities values DESPITE it being explicitly set immediately before SaveChanges is called. SaveChanges is resetting the Version to be the retrieved value not the set value.

在EDMX,版本被设置为具有一个StoreGeneratedPattern设置为已计算

In the EDMX, the Version is set to have a StoreGeneratedPattern is set to Computed.

任何人有任何想法是怎么回事?

Anyone have any idea what is going on here?

推荐答案

这是一个问题。一旦列设置为已计算你不能在应用程序中设置它的值(你可以,但不使用值)。

This is a problem. Once the column is set to Computed you can't set its value in the application (you can but the value is not used).

编辑:

如果您从数据库中加载实体是默认与上下文跟踪。上下文存储其原始值。原始值,例如用于快照更改跟踪,但他们也被用来作为已计算属性的唯一有效来源。如果您在实体集已计算属性未使用的价值和原始值insted的使用。解决方法是修改原来的值(修改任何东西前):

If you load entity from database it is by default tracked with the context. The context stores its original values. Original values are for example used for snapshot change tracking but they are also used as the only valid source of Computed properties. If you set Computed property in your entity the value is not used and original value is used insted. The workaround is to modify original value (before you modify anything else):

using (var context = new TestEntities())
{
    var entityToUpdate = context.MyEntities.Single(e => e.Id == someId);
    entityToUpdate.Timestamp = entity.Timestamp;

    ObjectStateEntry entry = context.ObjectStateManager.GetObjectStateEntry(entityToUpdate);
    entry.ApplyOriginalValues(entityToUpdate);

    // set modified properties
    context.SaveChanges();
}

编辑2:

顺便说一句。一旦你既实际加载时间戳和previously检索时间戳你可以简单地比较他们的应用程序中,而不是在数据库中做这件事。

Btw. once you have both actually loaded timestamp and previously retrieved timestamp you can simply compare them in your application instead of doing it in the database.

这篇关于实体框架乐观并发异常不存在的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆