C# 附加类型为的实体失败,因为相同类型的另一个实体已具有相同的主键值。
让我快速描述一下我的问题 我有5个客户的5个数据库,每个数据库都有一个名为SubnetSettings的表 我已经创建了一个下拉列表来选择客户,并将显示属于所选客户的SubnetSetting表,允许我创建、编辑和删除 我可以毫无问题地创建、删除,但是当我想要编辑数据时,它会带来错误: “/TMS”应用程序中的服务器错误 附加“CFS.Domain.Entities.SubnetSettings”类型的实体失败,因为相同类型的另一个实体已具有相同的主键值。如果图形中的任何实体具有冲突的键值,则在使用“Attach”方法或将实体状态设置为“Unchanged”或“Modified”时可能会发生这种情况。这可能是因为某些实体是新的,尚未收到数据库生成的键值。在这种情况下,使用“添加”方法或“添加”实体状态跟踪图形,然后根据需要将非新实体的状态设置为“未更改”或“已修改” 这是我在控制器中的编辑C# 附加类型为的实体失败,因为相同类型的另一个实体已具有相同的主键值。,c#,entity-framework,model-view-controller,primary-key,C#,Entity Framework,Model View Controller,Primary Key,让我快速描述一下我的问题 我有5个客户的5个数据库,每个数据库都有一个名为SubnetSettings的表 我已经创建了一个下拉列表来选择客户,并将显示属于所选客户的SubnetSetting表,允许我创建、编辑和删除 我可以毫无问题地创建、删除,但是当我想要编辑数据时,它会带来错误: “/TMS”应用程序中的服务器错误 附加“CFS.Domain.Entities.SubnetSettings”类型的实体失败,因为相同类型的另一个实体已具有相同的主键值。如果图形中的任何实体具有冲突的键值,则在
// 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中的保存方法
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;
}
我知道很难理解别人的代码。因此,任何建议都是非常感谢的。客观地综合答案: 您尝试更新的对象不是来自基对象,这是错误的原因。这个物体来自风景区的柱子 解决方案是从数据库中检索对象,这将使实体框架知道并在上下文中管理对象。然后,您必须获取从视图中更改的每个值,并包含在由实体控制的对象中
// 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);
Category categoryFromBase=Repository.GetById(categoryFromViewModel.Id);
CreateMap();
Mapper.Map(categoryFromViewModel、categoryFromBase);
Repository.Save(categoryFromBase);
我不确定下面这句话是否符合您的意图:
Mapper.Map<Category, Category>(categoryFromViewModel, categoryFromBase);
Mapper.Map(categoryFromViewModel,categoryFromBase);
我认为以下是你想要的:
Category categoryFromBase = Mapper.Map<Category>(categoryFromViewModel)
Category categoryFromBase=Mapper.Map(categoryFromViewModel)
为了避免那个恼人的消息,我不得不从数据库中加载记录,以便使用context.Entry(obj).State=EntityState.Modified代码>感谢您的澄清。我将ItemsSource绑定到XAML中的实体框架模型。然后我请求ItemsSource变量(这是一个ObservableCollection)并尝试更新它。这导致了上述错误。然后我试着用代码设置ItemsSource:ItemsSource=database_context.model.Local,它解决了我的问题。当我读到“你试图更新的对象不是来自基础的,这就是错误的原因。该对象来自视图的帖子。”这一切对我来说都很清楚。问题解决了。谢谢。请看一下我的答案。