EF 4.1 Code-First и ASP MVC 3 проблема при редактировании сущностей - PullRequest
0 голосов
/ 12 апреля 2011

Я закодировал свои сущности и создал DbContext. Затем я использовал MVC Scaffolding для создания простой формы CRUD для одного объекта. Пока все хорошо, все работает как рекламируется. Теперь я решил заменить сгенерированный скаффолдингом DbContext на простую обертку Service поверх DbContext. Все, что он делает, это делегирует DbContext.

Однако теперь у меня возникает проблема в следующей строке при попытке отредактировать сущность:

service.Entry(Book).State = EntityState.Modified;

«Объект с таким же ключом уже существует в ObjectStateManager. ObjectStateManager не может отслеживать несколько объектов с одним и тем же ключом »

Мне удалось решить это так:

PropertyInfo[] infos = typeof(Book).GetProperties();
foreach (PropertyInfo info in infos)
            {
                info.SetValue(internalBook, info.GetValue(book, null), null);
            }

По сути, я снова получаю объект и копирую свойства объекта, который был передан мне View. Я также отметил, что когда я получаю юридическое лицо, оно является доверенным лицом, а врученное мне - нет.

В чем может быть проблема?

Вот мой класс обслуживания:

 public class BookService
{

    private DbContext context;
    private DbSet<Book> set;    

    public BookService(DbContext context, DbSet<Book> set) {
        this.context = context;
        this.set = set;
    }

    public IQueryable<Book> Query
    {
        get { return set; }
    }

    public virtual void Add(Book entity)
    {
        set.Add(entity);
    }        

    public virtual void Remove(Book entity)
    {
        set.Remove(entity); 
    }

    public virtual void SaveChanges() {
        context.SaveChanges();
    }

    public List<Book> All() {
        List<Book> books = set.ToList();
        return books;
    }

    public DbEntityEntry<Book> Entry(Book book) {
        return context.Entry(book);
    }
}

Вот код действия редактора действия. Я прокомментировал оригинальный, сгенерированный скаффолдингом код:

    [HttpPost]
    public ActionResult Edit(Book book)
    {
        Book internalBook = service.Query.Single(b => b.Id == book.Id);
        if (ModelState.IsValid)
        {
            PropertyInfo[] infos = typeof(Book).GetProperties();
            foreach (PropertyInfo info in infos)
            {
                info.SetValue(internalBook, info.GetValue(book, null), null);
            }                
            service.Entry(internalBook).State = EntityState.Modified;                
            service.SaveChanges();

            //context.Entry(book).State = EntityState.Modified;
            //context.SaveChanges();
            return RedirectToAction("Index");
        }
        return View(book);
    }

Ответы [ 2 ]

1 голос
/ 22 апреля 2011

На самом деле вам не нужно запрашивать книгу, вы можете просто использовать эти две строки:

service.Entry(book).State = EntityState.Modified;
service.SaveChanges();

Так что это полный код:

[HttpPost]
public ActionResult Edit(Book book)
{    
    if (ModelState.IsValid)    
    {                     
        service.Entry(book).State = EntityState.Modified;
        service.SaveChanges();        

        return RedirectToAction("Index");    
    }    

    return View(book);
}

Вы можете скачатьполное решение из этого поста: http://blog.jorgef.net/2011/04/ef-poco-proxies-in-mvc.html

0 голосов
/ 12 апреля 2011

Вы не можете прикрепить книгу, потому что вы загрузили ее в том же контексте. Общий подход таков:

[HttpPost]
public ActionResult Edit(Book book)
{
    Book internalBook = service.Query.Single(b => b.Id == book.Id);
    if (ModelState.IsValid)
    {             
        service.Entry(internalBook).CurrentValues.SetValues(book);                
        service.SaveChanges();
        return RedirectToAction("Index");
    }
    return View(book);
}
...