我的模型应该放在哪里?Web层还是数据层?(MVC + NHibernate)

12

我正在使用MVC、Ninject和NHibernate搭建一个n层应用程序(这是我第一次使用这些技术)。为了清晰明了起见,这些层分别是“数据”层、“服务”层和“Web”层(都是独立的项目)。

在MVC中,您的模型位于“Models”文件夹中。似乎有必要将我的模型放在这里以创建强类型视图,并通常遵循MVC的哲学。

但是,在NHibernate中,我还需要我的模型在“数据”层中,以便进行映射,并且NHibernate可以实例化实际对象以返回到服务层。

在项目间复制这些类不符合DRY原则,并且将它们抽象成自己的库似乎与MVC不太兼容(无论是在实践还是哲学上都不行)。

有什么想法吗?您如何构建O / RM对象和MVC模型的结构?


1
我很好奇2年的时间如何证明了这个问题(调整,加强等)。MVC3 是否改变了方程?我准备创建一个遗留的nH数据层和EF之间的混合来支持脚手架。在今天混合NH和EF时,VS项目的分组是什么?-谢谢 - justSteve
现在怎么样?距离上面的问题被提出已经快两年了? - Pouya Barrach-Yousefi
5个回答

6

我将Entity Framework的模型/类保存在数据层,并使用MVC项目的Models文件夹来处理展示模型和模型绑定。


好的。看起来大家的共识是将Presentation Models保留在Web层,将Domain Models保留在Data层。那么我的Services层应该向Web层返回什么?它是否应该了解Presentation Models?或者它应该返回Domain Models? - Jeffrey Harrington
不,我认为服务不应该知道演示模型。实际上,服务可能无法了解所需的每个可能的演示模型。服务应返回传输对象,这些对象可以是实体类型。Web层可以将其转换为演示模型。 - Craig Stuntz
有道理。不过,将领域模型映射到表示模型似乎不太符合DRY原则,特别是当这两个模型非常相似时。 - Jeffrey Harrington
1
它们不是相同的。请考虑:PM 为数据绑定和用户语言进行了优化。它独立于视图/操作存在。DM 为与领域的其他部分兼容性进行了优化。LINQ 能够轻松转换它们。 - Craig Stuntz
话虽如此,对于它们恰好相同的情况,您可以将DM传递给视图。 - Craig Stuntz
1
+1 这很糟糕,但这是正确的方式。在 RoR 的世界里,我们通常只有一个单一的模型(而不是两个),而事情会很快变得混乱。 - Dan Rosenstark

6
数据模型是独立的。MVC中的模型是另一回事。它是您要显示的内容的模型,这可能是您的数据模型,也可能不是。 您的数据模型可能超越层,也可能不超过。
以标准注册表格为例。数据模型可能包括用户名、密码和一个登录历史记录类数组、指示其状态是否活动的标志以及其他许多东西。MVC中的模型可能只关心用户名和密码,并且用户需要输入两次密码。您的数据模型真的需要两个密码字段吗?否。但是MVC中的模型需要。因此,它们是两种不同的实体。

好的。所以似乎共识是将Presentation Models保留在Web层中,将我的Domain Models放在Data层中。那么我的Services层应该返回什么给Web层?它是否应该知道Presentation Models?或者它应该返回Domain Models? - Jeffrey Harrington
3
服务层应该返回数据模型。或者,你可以问自己...如果我有不同的接口访问我的服务会发生什么?服务层对前端了解得越少,从长远来看就越好。 - Jim Barrows

4

由于NHibernate,我将所有的模型都保存在数据层中。查看S#arp Architecture,可以很好地保持你的表现层清晰。模型不必在Web项目中物理定位,即可使视图强类型化。


1

在这里,您对DRY原则是正确的。我将我的LINQ-to-SQL对象与业务对象分开,并且存在一些重复,这让我感觉不好,但似乎没有简单的解决方法。

我在做MVC商店时看了Rob Conery的博客,做出了这个决定(ORM对象和业务对象)。


0
使用MVC,您需要将模型放在“Models”文件夹中。这似乎是必要的,以创建强类型视图并遵循MVC理念。
任何模型都不能忽略。如果有必要,我仍然会使用演示模型,但我不反对在视图中使用您的nhibernate实体。
使用NHibernate时,您实际上不需要数据层,因为Session本身就是数据层。
服务层似乎是个好主意,但前提是您打算为此层拥有多个客户端。
否则,我只会有一个项目,并使用命名空间来分离我的层。它构建更快,部署更容易。

使用NHibernate时,您实际上不需要数据层,因为Session本身就是数据层。为了实现存储库模式,我正在抽象化数据层。这样,我的服务针对接口编程,数据层很容易互换(即切换O / RM)。 - Jeffrey Harrington
你可以将实体放在核心库中,然后将存储库与服务一起放置。存储库也是服务。 - Simon Laroche

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接