问题
I am using EF4 in my ASP.NET MVC 2 web application. I am attempting to save data to a database. It is fairly straightforward to add new data to a database. I'm doing it something like this:
PeopleEntities entities = ObjectContextFactory.GetPeopleEntities();
entities.People.AddObject(person); // The Person object created from user input.
entities.SaveChanges();
However, this has the unfortunate side-effect of always saving a new object to my database. I do need this functionality (of course), but I also want the option to update an existing item in the database (or, save as new if the item does not yet exist in the database).
I tried replacing the second line above with something like this:
entities.People.ApplyCurrentValues(person);
but I am receiving this InvalidOperationException:
An object with a key that matches the key of the supplied object could not be found in the ObjectStateManager. Verify that the key values of the supplied object match the key values of the object to which changes must be applied.
This case happens whether I try to add a new person, or if I am trying to edit a person. What can I do to correct this issue?
Update to Question:
I tried the answers provided below, but when I went to debug the Single
statement, I found that the ID of the Person I was saving was always 0 - even if I had retrieved it from the database. So, I wanted to post what I am doing to retrieve the web application in the first place. Maybe this will help a bit.
When I navigate to a page displaying a Person's information, the address is:
http://localhost/Person/Index/1
where 1 is the ID of the Person in the database. I retrieve the Person through a repository method that contains the following line (entities is a member variable of the repository class):
public Person GetPerson(int id)
{
return entities.People.FirstOrDefault(p => p.PersonID == id);
}
This method is called from my project's controller. That looks like this:
public ActionResult Index(int id)
{
var entities = ObjectContextFactory.GetScenarioDBEntities();
Person person = new PersonRepository(entities).GetPerson(id);
return View("Index", person);
}
Now that I am looking at that, I wonder if it's wrong to instantiate a local entities object every time I want to retrieve a new Person. (Going to research that now.) In any case, when I do, ultimately go to save over the previous Person, I find that the PersonID value is always == 0.
回答1:
entities.SaveChanges();
is all you need, provided you retrieved the object from the same exact context. Otherwise, you'll need a call to entities.Attach(person);
.
This should work:
PeopleEntities entities = ObjectContextFactory.GetPeopleEntities();
var person = entities.People.Single(p => p.Id == id); // or some other way to get the person in question
// make changes to person ...
entities.SaveChanges();
回答2:
Try this:
public void UpdateEntity(Entity entity) {
var entityKeyObj = DataContext.Entity.Where(i => i.ID == entity.ID).First();
entity.EntityKey = entityKeyObj.EntityKey;
DataContext.ApplyCurrentValues("Units",entity);
SaveChanges();
}
回答3:
var entity = context.Table.Single(predicate);
entity.Field = "stuff";
context.SaveChanges();
来源:https://stackoverflow.com/questions/4630035/how-to-perform-an-update-using-objectcontext