数据库上下文插入和删除bug

时间:2014-03-06 03:14:39

标签: c# database entity-framework tsql

我试图将一些实体插入数据库上下文并删除它。

我现在遇到的麻烦是当我尝试删除它时,它给了我这个错误。

System.InvalidOperationException : The object cannot be deleted because it was not found in the ObjectStateManager.

所以我用谷歌搜索,人们告诉我给实体打电话.attach(),在我做完之后我得到了

System.InvalidOperationException : An object with the same key already exists in the       
ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same   
key.

无论哪种方式,它都不起作用 - -

一些代码:

    public void delete(WebPointOrderHead item)
    {
        WebDataEntities3 dbcDelete = this.dbc;
        WebPointOrderHead deleteItem = dbcDelete.WebPointOrderHeads.Where(p => (p.OrderID == item.OrderID)).First();
        dbcDelete.WebPointOrderHeads.Remove(item) ;
        dbcDelete.SaveChanges();
    }

    public void insert(WebPointOrderHead item)
    {

        WebDataEntities3 dbcinsert = this.dbc;
        WebPointOrderHead itemToAdd = BusinessLogic.calculatePoints(item, dbcinsert);
        var IDs = from id in dbcinsert.WEBIDs
                  where id.TableName.Equals("PointOrder_ID")
                  select id;
        IDs.First().NextID++;
        var highestID = (from c in dbcinsert.WebPointOrderHeads 
                         select c.OrderID).Max();
        itemToAdd.OrderID = highestID + 1;
        dbcinsert.WebPointOrderHeads.Add(itemToAdd);
        dbcinsert.SaveChanges();
    }

1 个答案:

答案 0 :(得分:2)

   public void delete(WebPointOrderHead item)
{
    WebDataEntities3 dbcDelete = this.dbc;
    WebPointOrderHead deleteItem = dbcDelete.WebPointOrderHeads.Where(p => (p.OrderID == item.OrderID)).First();
    dbcDelete.WebPointOrderHeads.Remove(item) ;
    dbcDelete.SaveChanges();
}

关于此片段的一些内容。

1)您可以将LINQ清理为:

    WebPointOrderHead deleteItem = dbcDelete.WebPointOrderHeads.First(x=>x.OrderID == item.OrderID); 

我首选的选择方法看起来更像是这样:

WebPointOrderHead deleteItem = dbcDelete.WebPointOrderHeads.FirstOrDefault(x=>x.OrderID == item.OrderID);
if(deleteItem == null)return;

通过这种方式,您可以使用更简洁的LINQ,并且只有在上下文中找到它时才会删除该记录。

2)您正在查询实体的上下文,但随后尝试删除分离的实体。您需要将.Remove(item)更改为.Remove(deleteItem);上下文不知道什么是项目。

3)寻址插入/更新逻辑。使用detatched实体时,需要检查ID。如果ID是> 0然后你需要使用.Attach(),如果ID是0你需要使用.Add()

4)我对你的插入代码块感到困惑,它看起来像你试图自己控制你的实体的ID。这有很多问题:不是线程安全,不需要,不是等等......如果你将一个实体Add()添加到没有ID的上下文中,它将被插入,并且假设你有一个身份,你的身份将被分配柱。如果Attach()具有现有ID的实体,则EF将生成Update语句。