0

In ASP.NET MVC project I try to update with method SaveItem item in repository. I use Entity Framework 6.1. I got the exception. How can I to solve this problem?

Attaching an entity of type 'Domain.Entities.Post' failed because another entity of the same type already has the same primary key value. This can happen when using the 'Attach' method or setting the state of an entity to 'Unchanged' or 'Modified' if any entities in the graph have conflicting key values. This may be because some entities are new and have not yet received database-generated key values. In this case use the 'Add' method or the 'Added' entity state to track the graph and then set the state of non-new entities to 'Unchanged' or 'Modified' as appropriate.

My repository:

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

In controller I imlpemented the logic of editing

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

}
MasterMedia
  • 315
  • 5
  • 13
  • Have you tried to run in debug mode with breakpoints to see what happens? – Will Marcouiller Sep 18 '14 at 14:06
  • yes I tried, it raised the exception – MasterMedia Sep 18 '14 at 14:39
  • And what were your variable values then, have you used some QuickWatch or something to see what happens under the hood? – Will Marcouiller Sep 18 '14 at 15:59
  • You might have a look at my answer on [ASP.NET MVC - Attaching an entity of type 'MODELNAME' failed because another entity of the same type already has the same primary key value](http://stackoverflow.com/questions/23201907/asp-net-mvc-attaching-an-entity-of-type-modelname-failed-because-another-ent/39557606#39557606). – Murat Yıldız Sep 18 '16 at 12:31

1 Answers1

0

The error message says:

"if any entities in the graph have conflicting key values".

Maybe your post is a new element but has associated elements (Author?) that already exist in the database. Then you must also "Attach" those items before adding your Post.


By the way, I think is better don't use directly the entity classes as your model for views.

Its better to use some "PostViewModel" class that exposes the information that must be show and maybe also a separated "EditPostViewModel" with edit data. Your controller should construct this classes and send it to views and also create your Post entity and send it to the repository (this is better done in a Service class) .

DaniCE
  • 2,412
  • 1
  • 19
  • 27