C# 实体框架“;ObjectStateManager中已存在具有相同密钥的对象我能';我不知道该怎么做,或者该怎么做

C# 实体框架“;ObjectStateManager中已存在具有相同密钥的对象我能';我不知道该怎么做,或者该怎么做,c#,asp.net,asp.net-mvc,entity-framework,C#,Asp.net,Asp.net Mvc,Entity Framework,我正在构建一个MVC3项目,首先使用Razor和实体框架代码。我有两种型号: public class Translation { public int TranslationId { get; set; } public string Pt { get; set; } public string Es { get; set; } public string En { get; set; } } public class Page { public in

我正在构建一个MVC3项目,首先使用Razor和实体框架代码。我有两种型号:

public class Translation
{
    public int TranslationId { get; set; }
    public string Pt { get; set; }
    public string Es { get; set; }
    public string En { get; set; }
}

public class Page
{
    public int PageId { get; set; }
    public Translation Title { get; set; }
    public Translation Description { get; set; }

    public int? ParentPageId { get; set; } // page can have a parent page
    public Page ParentPage { get; set; }   
}
我为页面模型的CRUD创建了PagesController。然后,我编辑了“创建”和“编辑”视图,为翻译属性添加了输入:

<div class="editor-field">
   @Html.EditorFor(model => model.Title.Pt)
   @Html.ValidationMessageFor(model => model.Title.Pt)
</div>
<div class="editor-field">
   @Html.EditorFor(model => model.Title.Es)
   @Html.ValidationMessageFor(model => model.Title.Es)
</div>
<div class="editor-field">
   @Html.EditorFor(model => model.Title.En)
   @Html.ValidationMessageFor(model => model.Title.En)
</div>

<div class="editor-field">
   @Html.EditorFor(model => model.Description.Pt)
   @Html.ValidationMessageFor(model => model.Description.Pt)
</div>
<div class="editor-field">
   @Html.EditorFor(model => model.Description.Es)
   @Html.ValidationMessageFor(model => model.Description.Es)
</div>
<div class="editor-field">
   @Html.EditorFor(model => model.Description.En)
   @Html.ValidationMessageFor(model => model.Description.En)
</div>
PagesController与创建时相同,因此不会进行额外附加。如果我在编辑视图中删除一个翻译输入,它不会抛出错误,但不会更新翻译

页面控制器代码:

private AdminEntities db = new AdminEntities();
    public ViewResult Index()
    {
        return View(db.Pages.ToList());
    }
    public ViewResult Details(int id)
    {
        Page page = db.Pages.Find(id);
        return View(page);
    }
    public ActionResult Create()
    {
        ViewBag.ParentPageId = new SelectList(db.Pages, "ParentPageId", "Description");
        return View();
    } 
    [HttpPost]
    public ActionResult Create(Page page)
    {
        if (ModelState.IsValid)
        {
            db.Pages.Add(page);
            db.SaveChanges();
            return RedirectToAction("Index");  
        }
        ViewBag.ParentPageId = new SelectList(db.Pages, "ParentPageId", "Description", page.ParentPageId);
        return View(page);
    }
    public ActionResult Edit(int id)
    {
        Page page = db.Pages.Find(id);
        ViewBag.ParentPageId = new SelectList(db.Pages, "ParentPageId", "Description", page.ParentPageId);            
        return View(page);
    }
    [HttpPost]
    public ActionResult Edit(Page page)
    {
        if (ModelState.IsValid)
        {
            db.Entry(page).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        ViewBag.ParentPageId = new SelectList(db.Pages, "ParentPageId", "Description", page.ParentPageId);
        return View(page);
    }
}
请注意,ViewBag.ParentPageId提供了一个我没有包含在视图代码中的页面列表,因为如果我删除了翻译内容,它就会工作

有什么想法吗

编辑:也许EF处理起来太复杂了?也许我应该换一个套路。

试试使用
db.Pages.Attach(第页)
db.ObjectStateManager.ChangeObjectState(第页,EntityState.Modified);
而不是
db.Entry(page).State=EntityState.Modified
它将附加修改后的实体

我犯了两个初学者的错误

错误#1:忘记在视图中添加翻译属性Id,因此可以在POST方法中绑定它们:

@Html.HiddenFor(model => model.Title.TranslationId)
@Html.HiddenFor(model => model.Description.TranslationId)
错误#2:翻译属性是Translation类的实例,必须在更新之前设置为modified:

db.Entry(page.Title).State = EntityState.Modified;
db.Entry(page.Description).State = EntityState.Modified;

db.Entry(page).State = EntityState.Modified;
db.SaveChanges();

现在可以了。我损失了几个小时,但至少我认为我学到了一些东西:)

我使用它是因为我已经创建了一个新实例,并填充了需要更新的属性

var key=this.CreateEntityKey("Pages",page); 
        ObjectStateEntry ose;
        if(this.ObjectStateManager.TryGetObjectStateEntry(key, out ose)){
            var entity=(Page)ose.Entity;
            Pages.Detach(entity);
        }
            this.Pages.Attach(page);

您可以发布编辑控制器代码吗?您需要将模型类中的属性声明为virtual@jayantha,我现在就这么做了,并在Entities.cs中添加了外键,但现在它避免了错误“发生引用完整性约束冲突:定义引用约束的属性值在关系中的主体对象和从属对象之间不一致。“为什么不使用POCO实体生成器之类的工具生成模型类呢。您需要有几种方法来修复实体框架中的导航属性。我直到现在才知道。我在试一下……啊。由于某些原因,db(Models.AdminEntities的实例)不包含ObjectStateManager的定义:|
var key=this.CreateEntityKey("Pages",page); 
        ObjectStateEntry ose;
        if(this.ObjectStateManager.TryGetObjectStateEntry(key, out ose)){
            var entity=(Page)ose.Entity;
            Pages.Detach(entity);
        }
            this.Pages.Attach(page);