使用实体框架同时更新和添加子行

时间:2013-01-03 14:15:40

标签: c# asp.net entity-framework

我在修改和同时添加子行时遇到了一些麻烦。我正在使用答案中的技巧:stackoverflow.com/questions/5557829/...

问题出在以下代码中:

public void EditReport(tbl_inspection inspection)
{
    foreach (var roll in inspection.tbl_inspection_roll)
    {                    
        container.tbl_inspection_roll.Attach(roll);
        container.ObjectStateManager.ChangeObjectState(roll, (roll.id_inspection_roll == 0) ? EntityState.Added : EntityState.Modified);
    }

    container.SaveChanges();
}

我总是至少有一行要更新。当我有1行添加时,它工作正常,问题是当我尝试同时添加多行时,显示众所周知的错误:

  

ObjectStateManager中已存在具有相同键的对象。   ObjectStateManager无法跟踪具有相同对象的多个对象   键。

感觉就像我在这里遗漏了一些东西......

2 个答案:

答案 0 :(得分:1)

我认为您需要从添加的内容中拆分修改后的内容。在您链接到Ladislav的问题中,以下代码为例:

if (myEntity.Id != 0)
{
    context.MyEntities.Attach(myEntity);
    context.ObjectStateManager.ChangeObjectState(myEntity, EntityState.Modified);
}
else
{
    context.MyEntities.AddObject(myEntity);
}

context.SaveChanges();

我认为特别使用Attach,而不是使用AddObject导致错误。

编辑:请尝试以下附件:

var r = new tbl_inspection_roll { id_inspection_roll = roll.id_inspection_roll };
container.tbl_inspection_roll.Attach(r);
container.Entry(r).CurrentValues.SetValues(roll);

答案 1 :(得分:1)

这里的问题是因为两个或多个子存根具有相同的键:0。一旦尝试连接第一个对象,它就会触发错误。

必须使用某种DTO重新设计该方法(我认为将ViewModel对象传递给域模型层并不正确,这就是我使用存根的原因)。或者调用一个函数来直接从Controller添加/修改。

编辑:

以下是代码:

public void EditReport(Inspection obj)
{
    var inspection = new tbl_inspection
    {
        id_inspection = obj.ID,
        code = obj.Code       
    };

    foreach (var roll in obj.Rolls)
    {                    
        var rollStub = new tbl_inspection_roll
        {
            id_inspection_roll = roll.ID,
            id_inspection = obj.ID,
            description = roll.Description
        };

        container.tbl_inspection_roll.Attach(roll);
        container.ObjectStateManager.ChangeObjectState(roll, (roll.id_inspection_roll == 0) ? EntityState.Added : EntityState.Modified);
    }

    container.tbl_inspection.Attach(inspection);
    container.ObjectStateManager.ChangeObjectState(inspection, EntityState.Modified);

    container.SaveChanges();
}

欢迎任何更好的解决方案......

相关问题