我有一个类似的模型:
public class Sample
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public Guid SampleId { get; set; }
public virtual SampleProperty Saloon { get; set; }
public virtual SampleProperty Room { get; set; }
public virtual SampleProperty Balcony { get; set; }
}
和相关实体:
public class SampleProperty
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public Piece Piece { get; set; }
public FloorType Floor { get; set; }
public WallType Wall { get; set; }
public DoorType Door { get; set; }
public WindowType Window { get; set; }
}
和SampleProperty实体中类型的相关枚举。
相关控制器是:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Sample(Sample model)
{
if (ModelState.IsValid)
{
db.Entry(model.Saloon).State = EntityState.Modified;
db.Entry(model.Room).State = EntityState.Modified;
db.Entry(model.Balcony).State = EntityState.Modified;
db.Entry(model).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(model);
}
get操作期间的控制器是:
[HttpGet]
public ActionResult Sample(Guid? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Sample @sample = db.Samples.Where(x => x.SampleId == id).FirstOrDefault();
if (@sample == null)
{
return HttpNotFound();
}
@sample.Room = new SampleProperties();
@sample.Saloon = new SampleProperties();
@sample.Balcony = new SampleProperties();
return View(@sample);
}
顺便说一下;我在View中包含以下属性;
@Html.HiddenFor(model => model.Saloon.Id)
@Html.HiddenFor(model => model.Room.Id)
@Html.HiddenFor(model => model.Balcony.Id)
我的问题是:当我尝试更新此实体时。我在下面有错误。你有什么想法吗?
附加类型的实体 'Project.Models.SampleProperties'失败了,因为另一个 相同类型的实体已具有相同的主键值。这个 使用“附加”方法或设置状态时可能会发生 如果图中的任何实体具有,则实体为“未更改”或“已修改” 冲突的关键值。这可能是因为一些实体是新的和 尚未收到数据库生成的键值。在这种情况下使用 “添加”方法或“已添加”实体状态可跟踪图表和 然后将非新实体的状态设置为“未更改”或“已修改”为 合适的。
答案 0 :(得分:1)
在我的情况下,这个异常被触发了,因为我正在使用相同的Pk两次附加相同的Entity(类)。 E.g:
db.Users.Attach(dbRecord.CreatorUser);
db.Users.Attach(dbRecord.OwnerUser); //<- If CreatorUser== OwnerUser then ERROR
您可以使用简单的比较来避免这种情况:
db.Users.Attach(dbRecord.CreatorUser);
if (dbRecord.CreatorUser.Pk != dbRecord.OwnerUser.Pk)
{
db.Cabinets.Attach(dbRecord.OwnerUser);
}
答案 1 :(得分:0)
附加“Project.Models.SampleProperties”类型的实体失败,因为同一类型的另一个实体已经具有相同的主键值。看起来您正在附加实体。
您尚未显示附加实体的代码(这会有所帮助)。但是,很可能实体已经以某种方式从数据库附加/实现到上下文。所以你要找的是the most reasonable way to find out if an entity is attached to the dbcontext。
您还有可能没有将模型附加(DbSet.Attach)回DbContext。
更新
我认为您的代码应如下所示:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Sample(Sample model)
{
if (ModelState.IsValid)
{
// Added Line
db.Samples.Attach(model);
db.Entry(model.Saloon).State = EntityState.Modified;
db.Entry(model.Room).State = EntityState.Modified;
db.Entry(model.Balcony).State = EntityState.Modified;
db.Entry(model).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(model);
}
答案 2 :(得分:0)
实际上,这不是我的问题的答案,但我找不到合适的解决方案,而不是将所有实体分配为同一实体中的单独对象,如:
public class Sample
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public Guid SampleId { get; set; }
public Piece SaloonPiece { get; set; }
public FloorType SaloonFloor { get; set; }
public WallType SaloonWall { get; set; }
public DoorType SaloonDoor { get; set; }
public WindowType SaloonWindow { get; set; }
public Piece RoomPiece { get; set; }
public FloorType RoomFloor { get; set; }
public WallType RoomWall { get; set; }
public DoorType RoomDoor { get; set; }
public WindowType RoomWindow { get; set; }
public Piece BalconyPiece { get; set; }
public FloorType BalconyFloor { get; set; }
public WallType BalconyWall { get; set; }
public DoorType BalconyDoor { get; set; }
public WindowType BalconyWindow { get; set; }
}
我知道,这不是很有魅力......