Search code examples
c#entity-frameworkasp.net-mvc-4sql-viewupdatable-views

Updatable View via Form?


Is it possible to update data via a form without binding the form to the original table?

We need users to update a small subset of data within the main table to which the SQL view is mapped, below is an example of the code used to update the data:

[HttpPost]
public ActionResult Address(AddressView model)
{
    if (ModelState.IsValid)
    {
        TestEntities.AddressView .AddObject(model);
        TestEntities.SaveChanges();

        return Redirect("/Customer?id=" + model.id);
    }

    return View(model);
}

Unfortunately because the view cannot contain a Primary Key, I get the following error when trying to update data:

Unable to update the EntitySet 'AddressView' because it has a DefiningQuery and no element exists in the element to support the current operation.

Is there a possible workaround without using a typical SQL Update statement, I would like to stick with Entity Framework if possible.


Solution

  • Here is my work around, essentially using the data from the initial view to present data to the model, then on post map the data to the actual table (used within initial view) that contains a Primary Key:

    public ActionResult Customer(int id)
    {
        var viewModel = new Customer();
    
        using (var testEntities = new TestEntities(new EntityConnection(StrEntities)))
        {
            var model = testEntities.CustomerView.Single(m => m.id == id);
    
            viewModel.id = id;
            viewModel.address_1 = model.address_1;
            viewModel.address_2 = model.address_2;
            viewModel.post_code = model.post_code;
        }
    
        return View("Customer", viewModel);
    }
    
    [HttpPost]
    public ActionResult Address(Address viewModel)
    {
        if (ModelState.IsValid)
        {
            using (var testEntities = new TestEntities(new EntityConnection(StrEntities)))
            {
                var model = testEntities.AddressTable.Single(m => m.id == viewModel.id);
    
                model.address_1 = viewModel.address_1;
                model.address_2 = viewModel.address_2;
                model.post_code = viewModel.post_code;
    
                testEntities.SaveChanges();
            }
    
            return Redirect("/Customer?id=" + viewModel.id);
        }
    
        return View(viewModel);
    }
    

    Hope this proves useful to others :-)