This is the code that I have in my controller:
[HttpPost]
public ActionResult UpdateArticle(Article article)
{
if (ModelState.IsValid)
{
article.DateAdded =
this.articleRepository.GetSingle(article.ID).DateAdded;
article.DateModified = DateTime.Now;
this.articleRepository.Update(article);
return this.Redirect("~/Admin");
}
else
{
return this.Redirect("~/Admin/UnsuccessfulOperation");
}
}
From the view the data comes updated. I have a generic repository which handles the saving.
Update looks like this:
public virtual void Update(T entity)
{
//this.context.Entry(entity).State = EntityState.Modified;
this.context.SaveChanges();
}
If I uncomment the first line
An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple
objects with the same key.
exception is thrown. When commented nothing is saved.
Any help is appreciated.
UPDATE
Ok the problem seems to be that the updated article is not “part” of the context so when I pass it to the update nothing happens. If I get the entity from the repository itself and pass the new values and after that pass this entity everything works as expected. This piece of code actually updates the date in the repository:
var art = this.articleRepository.GetSingle(article.ID);
art.Text = article.Text;
this.articleRepository.Update(art);
What I don’t get is that this works too:
var art = this.articleRepository.GetSingle(article.ID);
art.Text = article.Text;
this.articleRepository.Update(article);
UPDATE 2
Thanks to Vitaliy I now know that attaching is the key, but when I try to attach the new entity I get the same ugly exception
An object with the same key already…
UPDATE 3
As I am not allowed to answer my own question in less than 8h I suppose I have to make another update.
Ok, so this is what I did in order to successfully detach the old and attach the new entity:
public virtual void Update(T entity, object id)
{
this.context.Entry(this.GetSingle(id)).State = EntityState.Detached;
this.context.Entry(entity).State = EntityState.Added;
this.context.Entry(entity).State = EntityState.Modified;
this.context.SaveChanges();
}
I will think of a better way to pass the ID, as it is already part of the entity, perhaps with and interface “myInterface” that has the ID property in it and T will be of type “myInterface”.
Thanks a lot to Vitaliy.
You are updating article, which is not attached to Context, thus nothing will be saved.
Probably you intention was to change DateModified then you should do it like this: