I have an edit action configured that is not updating records but not throwing any exceptions. The update appears to have worked but the changes are not reflected in the database.
I am using EF and MVC3, i have an interface that defines save customer
public interface ICustomerRepository
{
//allows a sequence of customers to be displayed
IQueryable<Customer> Customers { get; }
//saves edits to customer records
void SaveCustomer(Cust开发者_运维技巧omer customer);
}
Then my implementation of this
public void SaveCustomer(Customer customer)
{
if (customer.CustomerId == 0)
{
context.Customers.Add(customer);
}
context.SaveChanges();
}
Then in the controller my get and post actions
public ViewResult Edit(int customerId)
{
Customer customer = repository.Customers.FirstOrDefault(c => c.CustomerId == customerId);
return View(customer);
}
[HttpPost]
public ActionResult Edit(Customer customer)
{
if (ModelState.IsValid)
{
repository.SaveCustomer(customer);
TempData["message"] = string.Format("{0} has been saved", customer.CustomerName);
return RedirectToAction("Index");
}
else
{
//there is something wrong with the data values
return View(customer);
}
}
Then in my view i have
@model CustomerOrders.Domain.Entities.Customer
@{
ViewBag.Title = "Admin: Edit" + @Model.CustomerName;
Layout = "~/Views/Shared/_AdminLayout.cshtml";
}
<h1>Edit @Model.CustomerName</h1>
using (Html.BeginForm("Edit", "Admin"))
{
<div class="left-column">
<div class="editor">@Html.EditorFor(model => model.CustomerId)</div>
<div class="label-for">@Html.LabelFor(model => model.CustomerName)</div>
<div class="editor">@Html.EditorFor(model => model.CustomerName)</div>
@Html.ValidationMessageFor(model => model.CustomerName)
</div>
<div class="middle-column">
<div class="label-for">@Html.LabelFor(model => model.PrimaryContactName)</div>
<div class="editor">@Html.EditorFor(model => model.PrimaryContactName)</div>
<div class="label-for">@Html.LabelFor(model => model.PrimaryContactNo)</div>
<div class="editor">@Html.EditorFor(model => model.PrimaryContactNo)</div>
</div>
<div class="right-column">
<input type="submit" value="Save" />
@Html.ActionLink("Cancel and return to list", "Index")
</div>
}
I also have a create method wired up to the same edit action and view which works fine. Not sure where i am going wrong, im new to MVC3 and not sure if my edit implementation is correct?
The simple answer is because your working in a stateless environment, unless your using self tracking entities, you need to Attach
the object to EF's graph.
I've had problems with edit in the past though. So i ended up going to the DB to fetch the object first, then merging in the changes i need, then doing Save.
You need to seperate your Create/Edit actions out. Simply checking if the ID > 0 to deem an edit is not enough, be more explicit.
So to sum up:
- Have one action method for new objects. Use context.AddObject in this scenario.
- Have another action method for modifying objects. Go get the object from the repository, merge in your changes (left to right, or auto mapper, or TryUpdateModel), and do context.SaveChanges.
Overall, it's a pain. Many developers (myself included) have gone through what you have.
精彩评论