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

本文关键字:实体 键值 另一个 失败 因为 同类型 类型 | 更新日期: 2023-09-27 18:05:43

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

我有5个数据库 5个客户和每个有相同的表称为SubnetSettings

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

我可以创建,删除没有问题,但当我想编辑数据时,它带来的错误:

'/TMS'应用程序服务器错误。

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

这是我在控制器中的编辑

    // 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的post .

解决方案是从基中检索对象,这将使实体框架知道并在上下文中管理对象。然后,您将不得不从视图中获取已更改的每个值,并包含在实体控制的对象中。

// 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);
}

为了消除这个错误,我使用AutoMapper在更新之前将视图模型对象复制到基对象中。

Category categoryFromBase = Repository.GetById(categoryFromViewModel.Id);
Mapper.CreateMap<Category, Category>();
Mapper.Map<Category, Category>(categoryFromViewModel, categoryFromBase);
Repository.Save(categoryFromBase);   

我不确定下面这行是不是在做你想做的事情:

Mapper.Map<Category, Category>(categoryFromViewModel, categoryFromBase);

我认为以下是你想要的:

Category categoryFromBase = Mapper.Map<Category>(categoryFromViewModel)
相关文章: