【问题标题】:Entity Framework 6 and ObjectCache: saving issuesEntity Framework 6 和 ObjectCache:保存问题
【发布时间】:2017-12-30 07:29:18
【问题描述】:

我正在使用 Entity Framework 6 和 ObjectCache 来缓存一些不经常更改的实体。但是在尝试保存缓存的实体时遇到错误,因为它们是从不同的上下文中检索的。在保存之前,我验证了对象的状态是分离的,但在我这样做之前无法摆脱该错误:

public void Save(Product obj)
{
    var objInDb = dbContext.Products.Find(obj.Id);

    if (objInDb == null)
    {
        dbContext.Products.Add(obj);
        dbContext.SaveChanges();
    }
    else
    {
        dbContext.Entry(objInDb).CurrentValues.SetValues(obj);
        dbContext.Entry(objInDb).State = EntityState.Modified;
        dbContext.SaveChanges();
    }
}

在实施所述解决方案后修复的原始错误: 附加类型为“C”的实体失败,因为同一类型的另一个实体已经具有相同的主键值。如果图中的任何实体具有冲突的键值,则在使用“附加”方法或将实体的状态设置为“未更改”或“已修改”时,可能会发生这种情况。这可能是因为某些实体是新实体,尚未收到数据库生成的键值。在这种情况下,使用“添加”方法或“已添加”实体状态来跟踪图形,然后将非新实体的状态设置为“未更改”或“已修改”。

原来的代码是:

if (obj.Id == 0)
{
    context.Products.Add(obj);
}
else
{
    context.Entry(obj).State = EntityState.Modified;
}

context.SaveChanges();

有没有更好的方法来处理这个问题?我真的不喜欢绕过我的缓存并访问数据库来获取对象,因为它看起来对我来说是不必要的。

【问题讨论】:

  • 当时无效的原始代码是什么?
  • 我刚刚在我的问题中添加了原始代码。
  • 您是否在您的上下文中启用了Configuration.ProxyCreationEnabled?我的猜测是您将代理存储在缓存中,而不是实际的实体类型。
  • 它已启用,但我也尝试在填充缓存之前停用它,然后重新激活它,但结果是一样的。
  • 您需要先停用,然后才能从上下文中检索实体。您可能还想禁用更改跟踪。

标签: entity-framework caching objectcache


【解决方案1】:

我认为不“击中” de db 的唯一方法是如下所示。请记住,根据您的第一个例外,您已经在其他地方“命中”了该实体的数据库。

if (obj.Id == 0)
{
    context.Products.Add(obj);
}
else
{
    var localProduct = context.Products.Local.FirstOrDefault(x => x.Id == obj.Id);
    if (localProduct == null)
    {
        context.Entry(obj).State = EntityState.Modified;
    }
    else
    {
        context.Entry(localProduct).CurrentValues.SetValues(obj);
    }
}
context.SaveChanges();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-25
    • 2015-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-05
    • 1970-01-01
    • 2013-12-25
    相关资源
    最近更新 更多