为什么Entity Framework在将状态设置为Modified时会抛出附加实体错误?

时间:2016-03-10 10:30:28

标签: c# entity-framework

由于出现常见的实体框架错误而感到困惑

  

"附加类型为' MyType'的实体失败是因为   另一个相同类型的实体已经拥有相同的主键   值。

我对这个错误的理解是,这意味着该对象类型的图形中有另一个对象,它具有重复的主键,防止附加第二个副本。

但这种理解肯定是错误的,因为错误发生在这里:

public void Update(MyType updateItem)
{
    if (updateItem != null)
    {
        // debug code, which tells me there is only one match
        var foo = Entities.MyTypes.Where(x => x.MyTypeId == updateItem.MyTypeId);

        if (Entities.MyTypes.Any(itm => itm.MyTypeId == updateItem.MyTypeId))
        {
            // error here
            Entities.Entry(updateItem).State = System.Data.Entity.EntityState.Modified;
        }
        else
        {
            Entities.MyTypes.Add(updateItem);
        }
    }
}

为了不尝试添加或重新附加新对象,它只是说现有对象被标记为已修改,对吧?

有人可以在这里向我解释这个过程,所以我可以尝试理解并解决问题吗?

编辑:这是它试图运行的SQL

exec sp_executesql N'SELECT 
CASE WHEN ( EXISTS (SELECT 
    1 AS [C1]
    FROM [dbo].[MyType] AS [Extent1]
    WHERE [Extent1].[MyTypeId] = @p__linq__0
)) THEN cast(1 as bit) ELSE cast(0 as bit) END AS [C1]
FROM  ( SELECT 1 AS X ) AS [SingleRowTable1]',N'@p__linq__0 int',@p__linq__0=4749

返回C1值1.跟踪中的下一个条目是记录错误的记录器。

1 个答案:

答案 0 :(得分:0)

经过多次浪费时间之后,我发现这是有效的,根据这个答案:https://stackoverflow.com/a/31771363/271907

// needs this namespace
using System.Data.Entity.Migrations;

public void Update(MyType updateItem)
{
    if (updateItem != null)
    {
        if (Entities.MyTypes.Any(itm => itm.MyTypeId == updateItem.MyTypeId))
        {
            try
            {
                Entities.Entry(updateItem).State = System.Data.Entity.EntityState.Modified;
            }
            catch
            {
                Entities.Set<MyType>().AddOrUpdate(updateItem);
            }
        }
        else
        {
            Entities.MyTypes.Add(updateItem);
        }
    }
}

但是,我必须承认我不明白为什么它完全有效,我仍然对原始错误的原因感到困惑。

我可能不需要那里的try / catch块 - 也许我应该换掉State = Modified来调用AddOrUpdate()。但是因为旧的代码功能正常,而且我不确定为什么会这样,所以我觉得把它放在一边是最明智的。