簡體   English   中英

實體框架“ObjectStateManager 中已存在具有相同密鑰的 object。” - 我不明白如何或從這里做什么

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM