在实体中引用具有不同名称的相同实体

时间:2014-01-01 20:01:04

标签: 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; 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'失败了,因为另一个   相同类型的实体已具有相同的主键值。这个   使用“附加”方法或设置状态时可能会发生   如果图中的任何实体具有,则实体为“未更改”或“已修改”   冲突的关键值。这可能是因为一些实体是新的和   尚未收到数据库生成的键值。在这种情况下使用   “添加”方法或“已添加”实体状态可跟踪图表和   然后将非新实体的状态设置为“未更改”或“已修改”为   合适的。

3 个答案:

答案 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; }
}

我知道,这不是很有魅力......