c# - 附加类型的实体失败,因为相同类型的另一个实体已经具有相同的主键值。

标签 c# entity-framework model-view-controller primary-key

让我快速描述一下我的问题。

我有 5 个客户的 5 个数据库每个数据库都有一个名为 SubnetSettings 的表

我已经创建了一个下拉列表来选择一个客户,并将显示属于所选客户的 SubnetSetting 表,并允许我创建、编辑和删除。

我可以毫无问题地创建、删除,但是当我想编辑数据时它会带来错误:

“/TMS”应用程序中的服务器错误。

附加“CFS.Domain.Entities.SubnetSettings”类型的实体失败,因为相同类型的另一个实体已经具有相同的主键值。如果图表中的任何实体具有冲突的键值,则在使用“附加”方法或将实体状态设置为“未更改”或“已修改”时可能会发生这种情况。这可能是因为某些实体是新实体,尚未收到数据库生成的键值。在这种情况下,使用“添加”方法或“添加”实体状态来跟踪图形,然后根据需要将非新实体的状态设置为“未更改”或“已修改”。

这是我在 Controller 中的编辑

    // GET: /SubnetSettings/Edit1/5   
    public ActionResult Edit1(short? id)  
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        SubnetSettings subnetsettings = detailView.SubnetSettings.SingleOrDefault(t => t.Id == id); 
        if (subnetsettings == null)
        {
            return HttpNotFound();
        } 
        return View(subnetsettings);
    }


    // POST: /SubnetSettings/Edit1/5   
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Edit1([Bind(Include = "Id,Name,fDialUp,fPulse,fUseExternalGSMModem,fGsmDialUp,bUploadMethodId")] SubnetSettings subnetsettings)
    {
        if (ModelState.IsValid)
            {
                templateDb2.Save(subnetsettings);   
                return RedirectToAction("Index");
            }
        return View(subnetsettings);
    }

这是EF中的Save方法

     public SubnetSettings Save(SubnetSettings subnetsettings) {

     if (subnetsettings.Id == 0){                        
         context.SubnetSettings.Add(subnetsettings);
     }
     else {

         context.SubnetSettings.Attach(subnetsettings);               
         context.Entry(subnetsettings).State = EntityState.Modified; 
     }
        context.SaveChanges();
        return subnetsettings;
    }

我知道很难理解别人的代码。所以任何推荐或建议都非常感谢。

最佳答案

客观综合答案: 您尝试更新的对象不是来自基础,这是错误的原因。该对象来自 View 的帖子。

解决方案是从基础中检索对象,这将使 Entity Framework 知道并管理上下文中的对象。然后,您将必须从 View 获取每个已更改的值,并包含在由 Entity 控制的对象中。

// POST: /SubnetSettings/Edit1/5   
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit1([Bind(Include = "Id,Name,fDialUp,fPulse,fUseExternalGSMModem,fGsmDialUp,bUploadMethodId")] SubnetSettings subnetsettings)
{
    if (ModelState.IsValid)
        {
            //Retrieve from base by id
            SubnetSettings objFromBase = templateDb2.GetById(subnetsettings.Id);

            //This will put all attributes of subnetsettings in objFromBase
            FunctionConsist(objFromBase, subnetsettings)

            templateDb2.Save(objFromBase);   
            //templateDb2.Save(subnetsettings);   

            return RedirectToAction("Index");
        }
    return View(subnetsettings);
}

关于c# - 附加类型的实体失败,因为相同类型的另一个实体已经具有相同的主键值。,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23922339/

相关文章:

c# - 如何使用 Automapper 完成以下映射?

unit-testing - 单元测试和有序测试 - 最佳实践

带有 JTree 的 Java Swing 应用程序 - MVC 设计 : Where to position a TreeModel object architecturally?

c# - 在 Windows Phone 8 中获取 UI 调度程序

c# - 将 Azure Functions 与事件中心集成

c# - 使用 Winpcap 重构 Tcp session

entity-framework - EF6 扩展 TPH 层次结构(混合 TPH 和 TPT)

c# - 将 0x0000000000000001 从字符串转换为 long

c# - 实体类型的 EF 条件包含

model-view-controller - MVC 模式是否描述角色或层?