苦苦于在DbContext

时间:2015-06-06 18:56:45

标签: c# entity-framework

我正在努力实现一个非常基本的" InsertOrUpdate()" DbContext上的方法。我尝试按照this post中的建议。

private static bool SaveItem<TEntity>(Object objToSave, TEntity existing = null) where TEntity : class
{
    try
    {
        /////////////////////////////////////////
        // BLOCK A
        if(existing != null)
            db.Set<TEntity>().Attach(existing);
        /////////////////////////////////////////
        db.Entry(objToSave).State = existing!=null ? EntityState.Modified : EntityState.Added;
        db.SaveChanges();
    } catch(Exception e)
    {
        Logger.Exception(e);
        return false;
    }
    return true;
}

示例调用如下:

SaveItem(item, db.MyInstances.Where(dbItem => dbItem.ID == item.ID).FirstOrDefault());

一些定义:

class MyInstancesDbContext: DbContext { ... }
private static MyInstancesDbContext db = new MyInstancesDbContext();

据我了解,在该电话中,.Where()将导致某种附件。所以我尝试了两个包括标有&#34; A&#34;并删除它。这两个都给我带来了同样的错误:

  

System.InvalidOperationException:附加类型&#39; ... MyInstance&#39;的实体。失败,因为a   另一个相同类型的实体已经具有相同的主键值。使用&#39;附加&#39;方法或将实体的状态设置为“未更改”#39;或者&#39;修改&#39;如果有的话   图中的tities具有冲突的键值。这可能是因为某些实体是新的并且尚未收到数据库生成的键值。在这种情况下,请使用&#39;添加&#39;方法或者&#39;   新增&#39;实体状态跟踪图形,然后将非新实体的状态设置为“未更改”。或者&#39;修改&#39;酌情。

我发现this popular related answer此错误,用户建议使用AsNoTracking(),但这让我觉得我没有从根本上理解某些内容或者试图忽略某些错误。

我非常感谢任何建议。

1 个答案:

答案 0 :(得分:0)

我认为您缺少的是DbContext跟踪实体,并且它不喜欢使用相同的主键跟踪相同类型的实体。

  1. 当你这样称呼时:

    db.MyInstances.Where(dbItem => dbItem.ID == item.ID).FirstOrDefault()
    

    如果数据库中存在主键== MyInstance,则您已将item.ID的实体加载到上下文中。

  2. 此行完全不需要,因为已经附加existing - 但这可能不会导致错误。

    if(existing != null)
      db.Set<TEntity>().Attach(existing);
    
  3. 问题可能在这里:

    db.Entry(objToSave).State = 
    existing != null ? EntityState.Modified : EntityState.Added;
    

    如果existing == null,您可能没问题,因为此行会附加objToSave,但如果存在existing,您就会遇到问题,因为您将会遇到问题尝试附加与objToSave具有相同类型和主键的existing

  4. 相反,您可以尝试使用objToSave设置附加实体的值:

    db.Entry(existing).CurrentValues.SetValues(objToSave);
    

    如果存在现有记录,则不会附加objToSave

    https://msdn.microsoft.com/en-us/data/jj592677.aspx