简体   繁体   English

域模型到ViewModel并使用MVC3中的存储库模式和实体框架再次返回

[英]Domain model to ViewModel and back again using repository pattern and Entity Framework in MVC3

I have read here http://lostechies.com/jimmybogard/2009/09/18/the-case-for-two-way-mapping-in-automapper/ about how you probably shouldn't be trying to un-flatten a flattened object, but considering how I am using a repository with Entity Framework, the Entity models are expected, not the ViewModels. 我在这里阅读http://lostechies.com/jimmybogard/2009/09/18/the-case-for-two-way-mapping-in-automapper/关于你怎么可能不应该试图解开一个扁平化对象,但考虑到我如何使用具有Entity Framework的存储库,实体模型是预期的,而不是ViewModels。

I started wondering whether I should be taking a different approach, does anyone have any best practices for this sort of thing? 我开始想知道我是否应该采取不同的方法,有没有人有这种事情的最佳做法? or is it just time to start using ValueInjector Using AutoMapper to unflatten a DTO ? 或者是时候开始使用ValueInjector 使用AutoMapper来解除DTO and not being too concerned with mapping RecipeCreateViewModel back to Recipe? 而不是太关心将RecipeCreateViewModel映射回Recipe?

Below is my code to give you an idea of what I have at the moment. 下面是我的代码,让您了解我目前拥有的内容。

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

If you follow the 'natural' (very subjective) flow it's like this 如果你遵循'自然'(非常主观)的流程就像这样

To create domain model 创建 模型

ViewModel -> Mapper -> Domain Entity -> Repository -> Mapper -> Persistence Entity ViewModel - > Mapper - > Domain Entity - > Repository - > Mapper - > Persistence Entity

To display the update view model 显示 更新视图模型

Persistence Entity -> Mapper -> ViewModel 持久性实体 - > Mapper - > ViewModel

In the first situation you process a dto into a domain entity (apply business rules etc) then send it to the repository where it's persisted in a specific way (EF entities) 在第一种情况下,您将dto处理为域实体(应用业务规则等),然后将其发送到存储库,并以特定方式保存(EF实体)

In the second situation, you want to load a view model (a DTO) which will be used to update the domain model. 在第二种情况下,您希望加载将用于更新域模型的视图模型(DTO)。 Instead of reloading the whole domain entity and then map it to the DTO you're doing it directly from the repository. 而不是重新加载整个域实体,然后将其映射到DTO,而是直接从存储库中执行。

You'll probably say this cases don't apply to you as you're working directly against EF. 您可能会说这种情况不适用于您,因为您直接针对EF工作。 Well, that's the trick, the domain model != persistence model != view model. 嗯,这就是技巧,域模型!=持久性模型!=视图模型。 They are all different and have different concerns. 它们各不相同,有不同的顾虑。

So, with proper separation you'll always have: view model -> map -> domain entity -> map -> persistnence entity and in opposite direction: persistence entity -> map -> view model 因此,通过适当的分离,您将始终拥有:视图模型 - >地图 - >域实体 - >地图 - >持久性实体和相反方向:持久性实体 - >地图 - >视图模型

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM