Entity Framework «Объект с таким же ключом уже существует в ObjectStateManager.»- Я не могу понять, как и что делать отсюда - PullRequest
3 голосов
/ 07 июня 2011

Я строю проект MVC3, сначала использую код Razor и Entity Framework.У меня есть две модели:

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

Я создал PagesController для CRUD для модели страницы.Затем я отредактировал представления 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 такой, каким он был создан, поэтому никаких дополнительных вложений не производится.Если я удаляю один из входов Translations в представлении Edit, он не выдает ошибку, но все равно не обновляет переводы.

Код 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 обрабатывать?Может быть, я должен изменить свой подход.

Ответы [ 3 ]

4 голосов
/ 07 июня 2011

решаемые

Я делал ошибки двух новичков.

Ошибка № 1: Забыл добавить Id свойств перевода в представление, чтобы их можно было связать в методе POST:

@Html.HiddenFor(model => model.Title.TranslationId)
@Html.HiddenFor(model => model.Description.TranslationId)

Ошибка № 2: свойства перевода, так как они являются экземплярами класса Translation, должны быть изменены как модифицированные перед обновлением:

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

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

Теперь работает. Я потерял несколько часов, но, по крайней мере, мне кажется, что я кое-что узнал :)

1 голос
/ 07 июня 2011

Попробуйте использовать db.Pages.Attach(page);<br> db.ObjectStateManager.ChangeObjectState(page, EntityState.Modified); вместо db.Entry(page).State = EntityState.Modified; это прикрепит объект как измененный

0 голосов
/ 07 июня 2012

Я использую это, потому что я уже создал новый экземпляр и заполнил свойства, которые мне нужно обновить.

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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...