在previous question,@ Darin Dimitrov answered:
在你的情况下,最糟糕的是 您正在使用Linq2Sql模型 在你的观点内,这是一个 我看到人们最糟糕的反模式 在ASP.NET MVC应用程序中执行。您 绝对应该使用视图 楷模。这就是观点应该是什么 从控制器传递而来 控制器应该从哪里获得 视图。
为什么将Linq2Sql对象作为模型传递它是如此糟糕?
答案 0 :(得分:5)
将Linq2Sql对象作为模型传递给视图和控制器是很糟糕的原因有很多,并且在单个答案中覆盖所有这些对象相对困难。所以,这是我的前三名:
关注点分离 - Linq2Sql对象中嵌入了DAL逻辑,这违反了SoC。此外,您可能希望验证从视图传递的数据,这应该在模型中完成(不是控制器!)。但是,如果您将此逻辑添加到L2S模型,那么您也违反了SoC(更不用说如果重新生成L2S模型,您的验证将被删除)
封装 - 您的L2S类有很多成员,您的视图和控制器可能不需要访问。一个合适的模型将封装这些成员以使其无法访问。
可维护性和可重用性 - 在某些时候,您可能决定要更改后备存储。如果你使用你的L2S类作为模型,那么你最终会触摸很多代码来进行更改,而如果你推出自己的模型,那么你只需要担心改变你的模型而不需要其他任何东西。另外,不要弄乱你的L2S模型(参见上面的SoC)意味着它们可以在各个项目中重复使用。
答案 1 :(得分:4)
除了Brian Driscoll的优秀答案之外,我还要在LINQ to SQL或Entity Framework中添加它,你并不总是知道你给出的对象上实际存在哪些值。假设您的视图模型包含来自Linq2Sql的User对象。你可能想做这样的事情:
Messages (<%: Model.User.Messages.Count() %>)
因为用户对象上存在Messages
属性,所以很容易认为这是完全正常的。但是,这一行动的结果并不完全清楚。
另一方面,如果您使用LINQ生成一个ViewModel,其中包含您知道生成视图所需的信息,它可能如下所示:
using (var context = _contextFactory.Get()) {
return (from u in context.Users
where u.UserId == userId
select new UserSummary {Name = u.Name, MessageCount = u.Messages.Count())
.Single();
}
这使用单个SQL查询来获取此视图所需的所有信息,同时忽略您不需要的任何信息(例如用户收件箱的全部内容)。如果未来某个开发人员想要向此视图添加信息,他们将不得不确保它作为数据访问逻辑的一部分填充在ViewModel上。
答案 2 :(得分:1)
不仅Linq-To-Sql对象,而且任何实体对象都不应该暴露给视图。
它向最终用户显示您的数据架构(黑客可能会觉得它很有用)
它违反了mvc中的关注分离原则。
当您的实体在视图中对象延迟加载时,在视图中使用数据访问逻辑并没有太大的不同。因此,分层应用程序的重点已经一去不复返了。