Проблема с SaveChanges () Entity Framework 4.1 - PullRequest
2 голосов
/ 17 апреля 2011

У меня проблема с сохранением изменений в базе данных.

Я обновляю модель A в моем контроллере, однако, когда я сохраняю изменения с помощью SaveChanges (), я получаю дублированный элемент в базе данных для B.

После вызова UpdateModel () я проверил свойство Bs, и оно было, как я и ожидал, однако сразу после вызова SaveChanges (), если я проверил свойство Bs, я увижу, что Id совершенно другой (новый Id и новый запись).

Мой класс похож на это:

public class A
{
    [HiddenInput(DisplayValue = false)]
    public int AId { get; set; }

    public string Name { get; set; }

    public virtual ICollection<B> Bs{ get; set; }
}

public class B
{
    [HiddenInput(DisplayValue = false)]
    public int BId { get; set; }

    public string Name { get; set; }

    public virtual ICollection<A> As{ get; set; }
}

Мой контроллер выглядит так:

    [HttpPost]
    public ActionResult Edit(A theA)
    {
        try
        {
           db.Entry(theA).State = EntityState.Modified;

           foreach (var item in theA.Bs)
           {
               db.Entry(item).State = EntityState.Modified;
           }

           db.SaveChanges();

           return RedirectToAction("Index");
        }
        catch
        {
            return View();
        }
    }

Я что-то не так делаю?

Заранее спасибо

1 Ответ

8 голосов
/ 17 апреля 2011

Это обычное поведение. Проблема в том, что EF не знает, что вы прикрепили существующий B, поэтому он автоматически вставляет новую запись. Вы должны сказать EF, что B существует, позвонив по номеру:

// here add B to the collection in the A and after that call:
dbContext.Entry<B>(someB).State = EntityState.Unchanged();

или прикрепив B перед добавлением его в коллекцию в A (я не уверен, возможно ли это при использовании UpdateModel в ASP.NET MVC).

dbContext.Bs.Attach(someB);
// now add B to the collection in the A

Другая возможность - сначала загрузить B из базы данных и добавить загруженный объект в коллекцию в A, но это дополнительная передача туда и обратно в базу данных.

int id = someB.Id;
var loadedB = dbCotnext.Bs.Single(b => b.Id == id);
someA.Bs.Add(loadedB);
dbContext.As.Add(someA);
dbContext.SaveChanges();

Вывод: каждый раз, когда вы вызываете Add, весь граф объектов отслеживается как вставленный, если вы сначала не присоединяете связанные сущности (перед тем, как добавить их к вставленному родителю - 2-й и 3-й пример) или если вы вручную не изменили состояние связанной сущности вернуться к неизменным после добавления родителя. (1-й пример).

...