Only Bolivian Here
Only Bolivian Here

Reputation: 36733

How to persist an Edit in MVC3?

public ActionResult Edit(int id)
{
    var productBrand = brandRepo.FindProductBrand(id);
    ProductBrandModel model = Mapper.Map<ProductBrand, ProductBrandModel>(productBrand);
    return View(model);
}

[HttpPost]
public ActionResult Edit(ProductBrandModel model)
{
    if (ModelState.IsValid)
    {
        var productBrand = brandRepo.FindProductBrand(model.BrandId);
        productBrand.Name = model.Name;               
        //How to persist that information?
    }
}

I have a EF generate class ProductBrand and a model for views called ProductBrandModel.

How would I persist the information of an edit using Entity Framework? Should my brandRepo have a void method called SaveChanges where in it I would go:

public void SaveChanges()
{
    dbEntities.SaveChanges();
}

Upvotes: 0

Views: 942

Answers (2)

Dennis Traub
Dennis Traub

Reputation: 51624

As you correctly assume, you have to commit your changes to the database using the .SaveChanges() method. In your case, brandRepo.SaveChanges() would delegate to dbEntities.SaveChanges().

As a side note: In simple cases a separate repository class only introduces complexity without really providing any benefit. Entity Framework's DbContext pretty much resembles a simple repository itself, so you don't need one on top.

Of course, for the sake of testability an indirection layer might make sense.

Without the repository your code could look somewhat like this:

public ActionResult Edit(int id)
{
    var productBrand = dbEntities.ProductBrands.Find(x => x.BrandId = id);
    ProductBrandModel model = Mapper.Map<ProductBrand, ProductBrandModel>(productBrand);
    return View(model);
}

[HttpPost]
public ActionResult Edit(ProductBrandModel model)
{
    if (ModelState.IsValid)
    {
        var productBrand = dbEntities.ProductBrands.Find(x => x.BrandId = id);
        // or something similar, I don't know the inner workings of your
        // brandRepo.FindProductBrand(id)

        productBrand.Name = model.Name;               
        dbEntities.SaveChanges();
    }
}

Upvotes: 1

Adam Tuliper
Adam Tuliper

Reputation: 30152

I like to have a save method in my repository in conjunction with an entity framework helper method I got from the net. The SaveCustomer is my repository class method and below it is the helper class. In your case you would pass your model into

brandRepository.SaveProdctBrand(productBrand)

(helps to spell out the names for good naming conventions and fxcop rules)

public void SaveCustomer(Customer customer)
{
  using (var ctx = new WebStoreEntities())
  {
    if (customer.CustomerId > 0)
    {
        //It's an existing record, update it.
        ctx.Customers.AttachAsModified(customer);
        ctx.SaveChanges();
    }
    else
    {
        //its a new record.
        ctx.Customers.AddObject(customer);
        ctx.SaveChanges();
    }
  }
}

The helper class is as follows

public static class EntityFrameworkExtensions
{
/// <summary>
/// This class allows you to attach an entity.
/// For instance, a controller method Edit(Customer customer)
/// using ctx.AttachAsModified(customer); 
/// ctx.SaveChanges();
/// allows you to easily reattach this item for udpating.
/// Credit goes to: http://geekswithblogs.net/michelotti/archive/2009/11/27/attaching-modified-entities-in-ef-4.aspx
/// </summary>
public static void AttachAsModified<T>(this ObjectSet<T> objectSet, T entity) where T : class
{
    objectSet.Attach(entity);
    objectSet.Context.ObjectStateManager.ChangeObjectState(entity, EntityState.Modified);
}

/// <summary>
/// This marks an item for deletion, but does not currently mark child objects (relationships).
/// For those cases you must query the object, include the relationships, and then delete.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="objectSet"></param>
/// <param name="entity"></param>
public static void AttachAsDeleted<T>(this ObjectSet<T> objectSet, T entity) where T : class
{
    objectSet.Attach(entity);
    objectSet.Context.ObjectStateManager.ChangeObjectState(entity, EntityState.Deleted);
}

public static void AttachAllAsModified<T>(this ObjectSet<T> objectSet, IEnumerable<T> entities) where T : class
{
    foreach (var item in entities)
    {
        objectSet.Attach(item);
        objectSet.Context.ObjectStateManager.ChangeObjectState(item, EntityState.Modified);
    }
}
}

Upvotes: 0

Related Questions