【问题标题】:Cannot modified the object in repository无法修改存储库中的对象
【发布时间】:2014-09-18 14:03:17
【问题描述】:

在 ASP.NET MVC 项目中,我尝试使用存储库中的 SaveItem item 方法进行更新。我使用实体框架 6.1。我得到了例外。我该如何解决这个问题?

附加类型为“Domain.Entities.Post”的实体失败,因为同一类型的另一个实体已经具有相同的主键值。如果图中的任何实体具有冲突的键值,则在使用“附加”方法或将实体的状态设置为“未更改”或“已修改”时,可能会发生这种情况。这可能是因为某些实体是新实体,尚未收到数据库生成的键值。在这种情况下,使用“添加”方法或“已添加”实体状态来跟踪图形,然后将非新实体的状态设置为“未更改”或“已修改”。

我的仓库:

public class BlogRepository<T> : IBlogRepository<T> where T : class
{
    private readonly DbContext context;
    private readonly IDbSet<T> dbSet;
    public BlogRepository()
    {
        this.context = new BlogDbContext();
        dbSet = context.Set<T>();
    }

    public BlogRepository(DbContext context, IDbSet<T> dbSet)
    {
        this.context = context;
        this.dbSet = dbSet;
    }

    public void SaveItem(T item)
    {
        object value = Reflector.GetPropertyValue(item);
        var foundItem = dbSet.Find((int) value);
        if (foundItem == default(T))
            dbSet.Add(item);
        else
        {
            context.Entry(item).State = EntityState.Modified;
        }
        context.SaveChanges();
    }

    public void Delete(T item)
    {
        dbSet.Remove(item);
        context.SaveChanges();
    }

    public T GetById(int id)
    {
        return dbSet.Find(id);
    }

    public IEnumerable<T> GetAll()
    {
        return dbSet.AsEnumerable();
    }
}

在控制器中我实现了编辑逻辑

 public class PostController : Controller  
 {
    private readonly IBlogRepository<Post> blogRepository;
    public PostController(IBlogRepository<Post> blogRepository)
    {
        this.blogRepository = blogRepository;
    }

    public ActionResult Index(int id = 1)
    {
        Post post = blogRepository.GetById(id);
        return View(post);
    }

    public ActionResult Edit(int id)
    {
        Post post = blogRepository.GetById(id);
        return View(post);
    }

    [HttpPost]
    public ActionResult Edit(Post post)
    {
        if (ModelState.IsValid)
        {
              blogRepository.SaveItem(post);
              return RedirectToAction("Index", new { id = post.Id });
        }

        return View(post);
    }

    public ActionResult Create()
    {
        return View("Edit", new Post {Date = DateTime.Now});
    }

}

【问题讨论】:

标签: c# asp.net-mvc entity-framework repository-pattern


【解决方案1】:

错误信息说:

“如果图表中的任何实体具有冲突的键值”。

也许您的帖子是一个新元素,但具有数据库中已经存在的相关元素(作者?)。然后,您还必须在添加帖子之前“附加”这些项目。


顺便说一句,我认为最好不要直接使用实体类作为视图模型。

最好使用一些“PostViewModel”类来公开必须显示的信息,也可以使用带有编辑数据的单独的“EditPostViewModel”。 您的控制器应该构建这些类并将其发送到视图,并创建您的 Post 实体并将其发送到存储库(最好在 Service 类中完成)。

【讨论】:

  • 类似“db.Authors.Attach(post.Author);”的东西?
  • contect.DbSet.Attach(item) 我这样做了,但它引发了同样的异常
  • 如果您的 Post 实体有其他实体作为属性,例如 post.Author,则必须附加此(当然,附加到他的 Autor 的 dbSet)
猜你喜欢
  • 1970-01-01
  • 2015-08-14
  • 2013-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-05
  • 2017-03-18
  • 1970-01-01
相关资源
最近更新 更多