实体未能与实体框架
我使用实体框架在我的Web API应用这样的修改:实体未能与实体框架
[HttpPut]
public System.Web.Mvc.JsonResult UpdateAccount(CollaborateurModel item)
{
if (ModelState.IsValid)
{
ApplicationUser user = UserManager.FindByIdAsync(item.id_user_fk).Result;
user.Roles.Clear();
UserManager.AddToRoleAsync(item.id_user_fk, item.Role);
ajt_collaborator entity = Mapper.Map<CollaborateurModel, ajt_collaborator>(item);
repo.UpdateCollaborateur(entity);
return new System.Web.Mvc.JsonResult { Data = true };
}
else
{
return new System.Web.Mvc.JsonResult { Data = false };
}
}
在BLL
public void UpdateCollaborateur(ajt_collaborator collaborateur)
{
if (cruder == null) cruder = new Crud<ajt_collaborator>();
cruder.Update(collaborateur);
}
在DAL
public bool Update(params T[] items)
{
if (context == null) context = GetContext();
try
{
foreach (T item in items)
{
context.Entry(item).State = System.Data.Entity.EntityState.Modified;
}
context.SaveChanges();
return true;
}
catch
{
return false;
}
}
例外是thr自己在Update
方法
失败附加类型的实体“sport.DAL.Entities.ajt_collaborator”的,因为同一类型的另一实体中已经有此主键值。当您使用“附加”方法或将“未更改”值或“已修改”设置为实体的状态时,可能发生这种情况,实体图形是否具有冲突关键值。一些实体可能是新的,可能还没有收到由数据库生成的任何键值。在这种情况下,使用“Add”方法或“Added”实体绘制图形,并将值“Unchanged”或“Modified”分配给除新实体以外的状态实体。
我需要知道
- 这是什么异常的原因是什么?
- 我该如何解决?
,如下图所示不要在ajt_collaborator entity
-
ajt_collaborator entity = Mapper.Map<CollaborateurModel, ajt_collaborator>(item);
而不是使用ajt_collaborator entity
Find
(或Where
等,这样就不会有一个新的对象,但我们可以让现有的对象,它已经填充存在于实体中),然后使用Automapper
将所有从item
的属性映射到entity
。最后使用映射的实体进行更新。
EF认为,上下文和数据库是不同步的,因为你是标记项为已修改但它不有其主键设置的值。
处理这种情况的典型模式是检查PK场,并设置相应的实体状态:
context.Entry(item).State = (item.PK == default(int)) ? System.Data.Entity.EntityState.Added : System.Data.Entity.EntityState.Modified;
(其中默认(INT)是你PK的数据类型)
在你的情况下,通过确保PK/key字段甚至被发送到该方法,以便它在自动映射时不会丢失,或者在调用Update之前从数据库中重新提取项目HOD。
而不是'映射器。Map(item);'你可以在实体上执行'Find',然后使用该对象进行更新? –
ramiramilu
@ramiramilu你的意思是找到实体,然后用Collaborate的属性填充它,而不是使用Automapper转换它?这怎么能改变结果呢? –
我想'Mapper.Map'会给你一个新的对象,然后你将'Modified'设置为新的对象。但是已经存在一个具有相同'id'的对象。这就是为什么你会得到这个错误。所以做一个'find',使用'Mapper.Map'这个对象来映射'CollaborateurModel'属性到对象,然后用它来更新。 – ramiramilu