我用我的实体编码并创建了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);
}
答案 0 :(得分:1)
实际上你不需要查询Book,你可以使用这两行:
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
答案 1 :(得分:0)
您无法附加图书,因为您已将图书加载到同一上下文中。一般方法是:
[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);
}