2012-03-28 83 views
4

我在這裏http://lostechies.com/jimmybogard/2009/09/18/the-case-for-two-way-mapping-in-automapper/如何你可能不應該試圖讀取非扁平化扁平物體,但考慮到我是如何使用存儲庫實體框架,實體模型是預期的,而不是ViewModels。域模型視圖模型,然後再返回使用存儲庫模式和Entity Framework在MVC3

我開始想我是否應該採取不同的方法,沒有任何人有這樣的事情的最佳做法?還是剛開始使用ValueInjector Using AutoMapper to unflatten a DTO?而不是太在意將RecipeCreateViewModel映射回配方?

下面是我的代碼給你什麼,我目前所面對的一個想法。

// Entities 
public class Recipe { 
    public int Id { get; set; } 

    public string Name { get; set; } 
    public Course Course { get; set; } 
} 

public class Course { 
    public int Id { get; set; } 
    public string Name { get; set; } 
} 

// View Model 
public class RecipeCreateViewModel { 
    // Recipe properties 
    public int Id { get; set; } 
    public string Name { get; set; } 

    // Course properties, as primitives via AutoMapper 
    [Required] 
    public int CourseId { get; set; } 
    // Don't need CourseName in the viewmodel but it should probably be set in Recipe.Course.Name 
    //public string CourseName { get; set; } 

    // For a drop down list of courses 
    public SelectList CourseList { get; set; } 
} 


// Part of my View 
@model EatRateShare.WebUI.ViewModels.RecipeCreateViewModel 
... 
<div class="editor-label"> 
    Course 
</div> 
<div class="editor-field"> 
    @* The first param for DropDownListFor will make sure the relevant property is selected *@ 
    @Html.DropDownListFor(model => model.CourseId, Model.CourseList, "Choose...") 
    @Html.ValidationMessageFor(model => model.CourseId) 
</div> 
... 


// Controller actions 

public ActionResult Create() { 
    // map the Recipe to its View Model 
    var recipeCreateViewModel = Mapper.Map<Recipe, RecipeCreateViewModel>(new Recipe()); 
    recipeCreateViewModel.CourseList = new SelectList(courseRepository.All, "Id", "Name"); 
    return View(recipeCreateViewModel); 
} 

[HttpPost] 
public ActionResult Create(RecipeCreateViewModel recipe) { 
    if (ModelState.IsValid) { 
     // set the course name based on the id that was posted 
      // not currently checking if the repository doesn't find anything. 
    recipe.CourseName = courseRepository.Find(recipe.CourseId).Name; 
      var recipeEntity = Mapper.Map<RecipeCreateViewModel, Recipe>(recipe); 
     recipeRepository.InsertOrUpdate(recipeEntity); 
     recipeRepository.Save(); 
     return RedirectToAction("Index"); 
    } else { 
     recipe.CourseList = new SelectList(courseRepository.All, "Id", "Name"); 
     return View(recipe); 
    } 
} 

回答

3

如果按照 '自然'(非常主觀的)流是這樣的

創建模型

視圖模型 - >映射 - >域實體 - >存儲庫 - >映射器 - >持久性實體

顯示更新視圖模型

持久性實體 - >映射 - >視圖模型

在您處理一個DTO到一個域實體(應用業務規則等),然後把它的第一種情況到以特定方式(EF實體)保存的存儲庫

在第二種情況下,您想要加載將用於更新域模型的視圖模型(DTO)。不是重新加載整個域實體,然後將其映射到DTO,而是直接從存儲庫執行。

你可能會說,你要對EF直接合作這個案件並不適用於你。那麼,這就是技巧,領域模型!=持久性模型!=視圖模型。他們都是不同的,有不同的擔憂。

因此,適當的分離,你會永遠擁有:視圖模型 - >地圖 - >域實體 - >地圖 - > persistnence實體,在相反的方向:持久性實體 - >地圖 - >視圖模型

+0

感謝Mike的回答,我的問題不是很清楚,因爲我不確定幾件事情,並且一次詢問幾件事情。即時消息關閉後,您已經清楚地瞭解了創建和顯示圖層。我一直在努力的問題是從視圖模型返回映射。 – Pricey 2012-03-29 15:53:45

+0

@MikeSW爲什麼在從PM轉換回VM時跳過域模型?從DM映射你的VM不是更好嗎?這樣你在上層只做一次。 – 2013-04-19 14:59:00

+0

@JoaoLeme不是。顯示更新視圖模型只需要從持久性實體已經可用的模型中保存數據。所以不是填充整個對象,而是直接查詢存儲以獲取相關數據。這幾乎是CQRS – MikeSW 2013-04-19 15:15:10