![](/img/trans.png)
[英]LINQ Initializer Throws a “An object with the same key already exists in the ObjectStateManager.”
[英]Entity Framework “An object with the same key already exists in the ObjectStateManager.” - I can't understand how, or what to do from here
我正在構建一個 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; }
}
我為頁面 model 創建了用於 CRUD 的 PagesController。 然后我編輯了 Create 和 Edit 視圖,為 Translation 屬性添加了輸入:
<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>
它在 Create 上運行良好,向 Translations 表中添加了兩個新行(一個由 Title_TranslationId 引用,另一個由 Description_TranslationId 引用)和輸入內容。 但是在更新時,我在行中收到提到的錯誤:
db.Entry(page).State = EntityState.Modified;
PagesController 與創建時一樣,因此不會進行額外的附加。 如果我在 Edit 視圖中刪除 Translations 輸入之一,它不會引發錯誤,但不會更新翻譯。
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 處理起來太復雜了? 也許我應該改變我的方法。
解決了
我犯了兩個初學者的錯誤。
錯誤 #1:忘記在視圖中添加翻譯屬性 ID,因此可以在 POST 方法中綁定它們:
@Html.HiddenFor(model => model.Title.TranslationId)
@Html.HiddenFor(model => model.Description.TranslationId)
錯誤 #2:翻譯屬性,因為它們是翻譯 class 的實例,必須在更新前設置為已修改:
db.Entry(page.Title).State = EntityState.Modified;
db.Entry(page.Description).State = EntityState.Modified;
db.Entry(page).State = EntityState.Modified;
db.SaveChanges();
現在可以了。 我失去了幾個小時,但至少我認為我學到了一些東西:)
嘗試使用db.Pages.Attach(page);
db.ObjectStateManager.ChangeObjectState(page, EntityState.Modified);db.Pages.Attach(page);
而不是
db.ObjectStateManager.ChangeObjectState(page, EntityState.Modified);db.Entry(page).State = EntityState.Modified;
它將附加修改后的實體
我使用它是因為我已經創建了一個新實例,並填充了我需要更新的屬性。
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);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.