Entity Framework: ViewModel for a domain

I am creating an MVC 3 website. I have a model that looks like this:

public class Survey { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public Guid Id { get; set; } public string Name { get; set; } public string Description { get; set; } public DateTime DateStart { get; set; } public DateTime DateEnd { get; set; } // Not in view public DateTime DateCreated { get; set; } // Not in view public DateTime DateModified { get; set; } } 

Based on this, I also have a viewing model for editing survey information:

 public class SurveyEditViewModel { public Guid Id { get; set; } public string Name { get; set; } public string Description { get; set; } public DateTime DateStart { get; set; } public DateTime DateEnd { get; set; } } 

When the user finishes editing, I would like to save the changes. Here is my postcontrol action:

  [HttpPost] public ActionResult Edit(SurveyEditViewModel model) { // Map the view model to a domain model using AutoMapper Survey survey = Mapper.Map<SurveyEditViewModel, Survey>(model); // Update the changes _repository.Update(survey); // Return to the overview page return RedirectToAction("Index"); } 

In my repository (so far this is generic), I have the following code:

  public void Update(E entity) { using (ABCDataContext context = new ABCDataContext()) { context.Entry(entity).State = System.Data.EntityState.Modified; context.SaveChanges(); } } 

When this is done, I get the following error: "A statement about updating, inserting or deleting affected an unexpected number of rows (0). Objects can be changed or deleted from the moment objects are loaded. Update ObjectStateManager records.

I think this should be expected. Matching a view model with a model does not give me the complete Survey object.

I could change my controller to look like this. And then it works:

 [HttpPost] public ActionResult Edit(SurveyEditViewModel model) { // Map the model to a real survey survey = _repository.Find(model.Id); survey.Name = model.Name; survey.Description = model.Description; survey.DateStart = model.DateStart; survey.DateEnd = model.DateEnd; // Update the changes _repository.Update(survey); // Return to the overview page return RedirectToAction("Index"); } 

But I was wondering if a better way is available?

+4
source share
1 answer
 [HttpPost] public ActionResult Edit(SurveyEditViewModel model) { // Fetch the domain model to update var survey = _repository.Find(model.Id); // Map only the properties that are present in the view model // and keep the other domain properties intact Mapper.Map<SurveyEditViewModel, Survey>(model, survey); // Update the changes _repository.Update(survey); // Return to the overview page return RedirectToAction("Index"); } 
+12
source

All Articles