C# 引用实体中具有不同名称的相同实体
我有一个这样的模型:C# 引用实体中具有不同名称的相同实体,c#,asp.net-mvc,entity-framework,C#,Asp.net Mvc,Entity Framework,我有一个这样的模型: public class Sample { [Key] [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] public Guid SampleId { get; set; } public virtual SampleProperty Saloon { get; set; } public virtual SampleProperty Room { get;
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);
}
顺便说一下;我在考虑中包括以下财产:
@Html.HiddenFor(model => model.Saloon.Id)
@Html.HiddenFor(model => model.Room.Id)
@Html.HiddenFor(model => model.Balcony.Id)
我的问题是:当我尝试更新这个实体时。我下面有个错误。你知道吗
附加类型为的实体
“Project.Models.SampleProperties”失败,因为另一个
相同类型的实体已具有相同的主键值。这
在使用“附加”方法或设置
如果图形中的任何实体已更改,则将实体更改为“未更改”或“已修改”
相互冲突的键值。这可能是因为一些实体是新的和
尚未收到数据库生成的键值。在这种情况下,请使用
“添加”方法或“添加”实体状态来跟踪图形和
然后将非新实体的状态设置为“未更改”或“已修改”,如下所示
合适
附加“Project.Models.SampleProperties”类型的实体失败,因为相同类型的另一个实体已具有相同的主键值。`您似乎正在附加实体
您尚未显示附加实体的代码(这将很有帮助)。但是,实体很可能已经以某种方式从数据库附加/物化到上下文。所以你要找的是一份工作
还有一种可能是您没有将()模型附加回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);
}
事实上,这不是我问题的答案,但我找不到一个合适的解决方案,而不是将所有实体作为同一实体中的独立对象分配,如:
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; }
}
我知道,这并不迷人…在我的例子中,这个异常被触发是因为我用相同的Pk两次附加相同的实体(类)。例如:
db.Users.Attach(dbRecord.CreatorUser);
db.Users.Attach(dbRecord.OwnerUser); //<- If CreatorUser== OwnerUser then ERROR
我认为你是对的,我在那里犯了一个错误,宣布它们是新的,但我真的不知道什么是正确的方式。因此,我对问题进行了修改,并添加了您要求的缺失部分。根据您的评论进行了更新。很抱歉,我的回复晚了,但没有。我认为最好为每种类型使用单独的实体移动您是否以任何方式防止将两个(或三个)的
SampleProperty
引用设置为同一个对象?如果没有,那么可能会出现异常,因为您可以附加相同的密钥两次。无论如何,我认为你最好把它转换成1:n的关联。我不想创建具有相同属性的单独对象。当然,如果我们找不到解决方案,这可能是一个选择。非常感谢。你可以看看我的答案。
db.Users.Attach(dbRecord.CreatorUser);
if (dbRecord.CreatorUser.Pk != dbRecord.OwnerUser.Pk)
{
db.Cabinets.Attach(dbRecord.OwnerUser);
}