4

I searched on google but it seems to be too obvious and nobody is talking about this.

I have a repository for my table and I want to be able to update my db.

On Linq2Sql you have something like:

public void SaveCar(Car car)
{
    if (carTable.GetOriginalEntityState(car) == null)
    {
        carTable.Attach(product);
        carTable.Context.Refresh(RefreshMode.KeepCurrentValues, car);
    }
    carTable.ContextSubmitChanges();
}

and in the controller, just call this method on the POST Edit method.

How I do something like this in EF? The better way.

I see code using TryUpdateModel(model) but I'm not sure if that update what I have on the DB or I have to pick the object first and update it using a FormCollection...

I'm quite confused, I just need to get a Car from the form and update the car with the same ID from the db. So, what I have to do in the controller and repository?

Thank you.

EDIT: If I wasn't clear, I don't really know if that I put there is what I need converted to EF. I just want to know how I update an instance of an object using EF (EFCodeFirst is what im using). How I receive a instance from a form and update it in the db.

Jesus Rodriguez
  • 11,918
  • 9
  • 64
  • 88
  • Check this answer: http://stackoverflow.com/questions/3594515/how-to-update-an-entity-in-entity-framework-4-net/3594608#3594608 It is not directly related to MVC but it shows two different approaches to handle saving. In MVC use TryUpdateModel. – Ladislav Mrnka Feb 28 '11 at 07:05
  • My context doesnt have the ObjectStateManager (my context is created by hand for EFCodeFirst) so I can't use that. But thanks :) – Jesus Rodriguez Feb 28 '11 at 13:05

2 Answers2

2

The TryUpdateModel method can be used to assign values to an object, using a mapping between it's property-names and the values specified in the web-request. That being said, you can achieve the same behavior by doing something like this:

[HttpPost]
public ActionResult Edit(int id, FormCollection form)
{
    Car entity = new Car { Id = id };

    // This will attach the car entity to the content in the unchanged state.
    this.EntityFrameworkObjectContext.Cars.Attach(car);

    TryUpdateModel(entity, form.ValueProvider.ToXYZ()); // Can't remember the exact method signature right now

    this.EntityFrameworkObjectContext.SaveChanges();
    ...
}

When attaching an entity to the context, you're basically just notifying the context that you have an entity, which he should take care of. Once the entity is attached, the context will keep track of the changes made to it.

But this method is only suitable for scalar properties, since navigation properties are not updated using this method. If you have foreign-key properties enabled (like a Product assigned to a Category also has a CategoryId property, which links the two), you should still be able to use this method (since the navigation property is mapped using a scalar property).

Edit: Another way is to accept a Car instance as parameter:

[HttpPost]
public ActionResult Edit(int id, Car car)
{
    Car entity = new Car { Id = id };

    // This will attach the car entity to the content in the unchanged state.
    this.EntityFrameworkObjectContext.Cars.Attach(entity);

    // It is important that the Car instance provided in the car parameter has the
    // the correct ID set. Since the ApplyCurrentValues will look for any Car in the
    // context that has the specified primary key of the entity supplied to the ApplyCurrentValues
    // method and apply it's values to those entity instance with the same ID (this
    // includes the previously attached entity).
    this.EntityFrameworkObjectContext.Cars.ApplyCurrentValues(car); 
    this.EntityFrameworkObjectContext.SaveChanges();
    ...
}

You could also roll your own ModelBinder that actually has a reference to your Entity Framework Context and looks whether an Car.Id was specified in the form/query. If an ID is present you can grab the entity to update directly from the context. This method requires some effort, since you must make sure that you search for ID first and then apply all specified property-values. If you are interested I can give you some examle for this.

J. Tihon
  • 4,439
  • 24
  • 19
  • That's good one, but I think that is cleaner if I receive a Car instance in the Edit method instead of FormCollection. I think that there is a way to update my entities directly. – Jesus Rodriguez Feb 28 '11 at 13:07
2

A month, no answer, is time to autorespond.

The answer to my question is:

In the controller is something like:

if (ModelState.IsValid)
    repo.SaveCar(car);

and in the repo:

context.Entry(Car).State = EntityState.Modified;

Just that, that's the way to save objects.

Jesus Rodriguez
  • 11,918
  • 9
  • 64
  • 88