1

在我的 WCF 服务的业务逻辑中,大部分需要定位实体的地方,我都使用这种语法:

public void UpdateUser(Guid userId, String notes)
{
    using (ProjEntities entities = new ProjEntities())
    {
          User currUser = entities.SingleOrDefault(us => us.Id == userId);
          if (currUser == null)
               throw new Exception("User with ID " + userId + " was not found");
    }
}

我最近发现DbContextFind方法,我知道我现在可以这样做:

public void UpdateUser(Guid userId, String notes)
{
    using (ProjEntities entities = new ProjEntities())
    {
          User currUser = entities.Find(userId);
          if (currUser == null)
               throw new Exception("User with ID " + userId + " was not found");
    }
}

注意:“userId”属性是表的主键。

我读到,当使用Find方法实体框架时,首先检查实体是否已经在本地内存中,如果是的话 - 从那里带来它。否则 - 访问数据库(相SingleOrDefault对于总是访问数据库)。

我想知道我现在是否将所有用途都转换为SingleOrDefaulttoFind是否有任何潜在危险?

Find如果我使用它从内存而不是数据库中获取数据,是否有可能获得一些尚未更新的旧数据?

如果我在内存中有用户,并且有人更改了数据库中的用户,会发生什么 - 如果我现在总是使用这个“内存”副本而不是总是从数据库中获取最新更新的副本,这会不会有问题?

4

1 回答 1

0

如果我使用 Find 并且它从内存而不是数据库中获取数据,我是否有可能获得一些尚未更新的旧数据?

我想你已经在这里回答了你自己的问题。是的,使用Find您最终可能会返回与您的数据库不同步的实体,因为您的上下文具有本地副本。

在不了解您的具体应用的情况下,任何人都无法告诉您更多信息;您是长时间保持上下文活动还是打开它,进行更新并关闭它?显然,您保留上下文的时间越长,您就越容易检索到最新的实体。

我可以想到两种策略来解决这个问题。第一个在上面概述;打开你的上下文,做你需要的,然后处理它:

using (var ctx = new MyContext())
{
    var entity = ctx.EntitySet.Find(123);
    // Do something with your entity here...
    ctx.SaveChanges();
}

其次,您可以检索实体的DbEntityEntry并使用该GetDatabaseValues方法使用数据库中的值对其进行更新。像这样的东西:

var entity = ctx.EntitySet.Find(123);

// This could be a cached version so ensure it is up to date.
var entry = ctx.Entry(entity);
entry.OriginalValues.SetValues(entry.GetDatabaseValues());
于 2013-05-09T20:29:57.223 回答