4

我正在構建一個MVC 3網站。我有一個模型看起來像這樣:在此基礎上實體框架:ViewModel到域模型

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; } 
} 

我也有一個視圖模型編輯調查信息:

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; } 
} 

當用戶完成編輯,我想堅持的變化。這裏是我的控制器後的行動:

[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"); 
    } 

在我的倉庫(這是一個通用的一個現在)我有以下代碼:

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

當這個執行我收到以下錯誤:「商店更新,插入或刪除語句影響了意外數量的行(0)。實體可能已被修改或刪除,因爲實體已加載。刷新ObjectStateManager條目。「

我想這是可以預料的。從視圖模型到模型的映射不會給我一個完整的Survey對象。

我可以修改我的控制器,看起來像這樣。然後它的工作原理:

[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"); 
} 

但我想知道是否有更好的方法可用?

回答

12
[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"); 
} 
+0

太棒了!我會將其標記爲答案。 – Aetherix

+0

@DarinDimitrov如果我遵循這個例子,我的實體必須設置變更追蹤?我想如果將其設置爲啓用,我會遇到很多問題。 – MuriloKunze