2012-03-28 84 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