Entity framework EF实体作为域模型,何时使用视图模型将其与视图分离?

Entity framework EF实体作为域模型,何时使用视图模型将其与视图分离?,entity-framework,asp.net-mvc-2,viewmodel,Entity Framework,Asp.net Mvc 2,Viewmodel,我正在努力了解我的MVC2站点的最佳体系结构 由于我一直在尝试使用实体框架从数据库中获取数据,我开始意识到迄今为止我构建的简单域模型并不符合我计划视图的所有需求。因此,我正在考虑以下这个问题的简要答案: 但在领域模型和EF模型之间似乎存在冗余,几乎没有什么回报,我甚至无法理解概念上的差异。我不需要在将来切换数据源,我也不认为需要切换ORM解决方案 问题: 如果我遵循这个模式,因为我使用的是实体框架,那么我不应该直接使用EF实体作为域模型吗?(注意:我还没有考虑过如何解决这个问题,但也欢迎回答。)

我正在努力了解我的MVC2站点的最佳体系结构

由于我一直在尝试使用实体框架从数据库中获取数据,我开始意识到迄今为止我构建的简单域模型并不符合我计划视图的所有需求。因此,我正在考虑以下这个问题的简要答案:

但在领域模型和EF模型之间似乎存在冗余,几乎没有什么回报,我甚至无法理解概念上的差异。我不需要在将来切换数据源,我也不认为需要切换ORM解决方案

问题:

如果我遵循这个模式,因为我使用的是实体框架,那么我不应该直接使用EF实体作为域模型吗?(注意:我还没有考虑过如何解决这个问题,但也欢迎回答。)还是建议我管理一组单独的域模型

看来你这里有些多余的东西。阅读你的段落:

但这似乎是多余的 我能感觉到的一点回报 在域模型和EF之间 模特们,我甚至几乎不能 理解概念上的差异

我认为EF模型和您的域模型之间没有真正的区别。在我创建的项目中,我的EF模型是我的领域模型

但是,我的域模型类与ViewModels不同。域模型类可能包含视图不感兴趣的数据,或者视图需要根据视图中的信息计算/评估的信息。一个简单的例子可能是:

public class Session // Domain model (and EF Model
{
    public int Id {get; set; }
    public DateTime Start {get; set; }
    public int DurationInMinutes {get; set; }

}

public class SessionViewModel // The viewmodel :p
{
   public DateTime Start {get; set; }
   public int DurationInMinutes {get; set;}
   public DateTime End 
   {
       get
       {
            return Start.Add(TimeSpan.FromMinutes(DurationInMinutes));
       }
   }
}
在本例中,我对在视图中显示实际结束时间感兴趣,但对将其存储在数据库中不感兴趣,因为这可能会导致数据差异(如果数据在保存时损坏,则DurationInMinutes+Start可能不等于End)

当我第一次开始以这种方式编码时,我完成了大量的手工工作,将我的域模型映射到ViewModels,然后再映射回来。AutoMapper改变了这一切:)谷歌,或者NuGet,它会让你的生活变得更轻松:)

希望这有点帮助。如果我完全没有抓住要点,请发表评论:)

更新以处理评论

DataAnnotations随后将应用于ViewModel,因为DataAnnotations通常表示数据在视图中的显示和验证方式

例如,您可以将
[Required]
属性放在
公共日期时间开始{get;set;}
上,以便Html.DisplayFor扩展根据您的数据批注自动验证Html

根据定义(无论如何,有些人认为),域模型不应该包含任何与业务逻辑相关的代码或逻辑。域模型只负责根据您的数据存储包含非常原始的数据。就我个人而言,我喜欢在两者之间放置某种服务层,负责获取数据和返回ViewModels,同时也负责执行相反的操作

最终目标是避免直接从控制器引用domainmodel

当然,所有这些要点都必须根据项目的规模进行权衡。仅仅为了模拟一个测试站点而做这一切当然是过火了——但在任何其他项目中,如果您实际部署的东西可能会扩展、扩展或改变,那么这是一个很好的习惯做法,因为它会大大提高您这样做的能力


这种方法的另一个关键点是,您必须将您的操作抽象为更小、更易于管理的单元,从而实现更好、更精确的单元测试。

只是想澄清一下:您目前正在使用EF类作为域模型,对吗?您还没有创建过作为域模型的重复类吗?是的,我创建过(这似乎是多余的,因此这是一个问题),但到目前为止,仅在一个实体上进行测试,以了解如何通过层(从控制器到数据存储)垂直集成所有内容,以进行基本crud操作。我想你会同意这完全没有必要。我的挑战是从一本只介绍Linq2SQL(而不是EF)的书(Pro ASP.Net MVC2 Framework)中学习,并填写web上各种文章中缺失的部分。我的回答有帮助吗?@Yngve:有,请看下面的评论。是的,你看吧。更新了我的答案:)你肯定在回答我的问题。一个相关的问题:那么,您如何在域模型上应用数据注释?是否要进入EF model.Designer.cs文件并在其中添加代码?在我的参考书中,只介绍了使用Linq2SQL的MVC2,注释被应用到手工编码的域模型中。所以,我认为作为域模型可能更好地被认为是viewmodel,它恰好镜像了我的实体(域模型),因为我现在只处理CRUD操作。我可以接受。我已经让Automapper在存储库(服务层?)中运行得相当好,这对于创建一个通用存储库来支持我所有实体类型的这些基本CRUD操作似乎非常有用。这听起来像是我在正确的轨道上吗?是的,看起来你在正确的轨道上!我将坚持使用您在这里描述的术语-视图模型作为第一个,域模型作为实体模型。存储库/服务层实际上取决于它实际在做什么,如果您不确定它是否真的是存储库层,请将其称为服务层:)请坚持使用这些名称,随着你的项目越来越大,在这里就StackOverflow提出好的问题会容易得多:)我最近在DDD上经历了一次相当严重的大脑转储,并试图让它与E一起工作