C# 为什么不';不要在视图中使用存储库

C# 为什么不';不要在视图中使用存储库,c#,asp.net-mvc,entity-framework,razor,repository,C#,Asp.net Mvc,Entity Framework,Razor,Repository,我有一个局部视图,它通过它的模型(一个事物列表)循环显示thing.Name和三个相关实体计数的整数值 首先,我试着放:(假剃刀) 但是它真的很慢。。。因此,我在ThingRepository中创建了一个函数,可以更快地执行相同的查询,类似这样的(伪代码) 而且速度快得多,所以我想叫它。我想我应该从控制器调用它,但是我需要一个ViewModel来保持(thing,int,int,int)集合作为模型,或者我可以使用ViewBag将结果传递给视图,但是,问题是: 为什么不直接从视图中使用存储库呢?

我有一个局部视图,它通过它的模型(一个事物列表)循环显示thing.Name和三个相关实体计数的整数值

首先,我试着放:(假剃刀)

但是它真的很慢。。。因此,我在ThingRepository中创建了一个函数,可以更快地执行相同的查询,类似这样的(伪代码)

而且速度快得多,所以我想叫它。我想我应该从控制器调用它,但是我需要一个ViewModel来保持(thing,int,int,int)集合作为模型,或者我可以使用ViewBag将结果传递给视图,但是,问题是: 为什么不直接从视图中使用存储库呢?视图中的代码有什么问题?(假剃须刀)

您能告诉我为什么不应该在视图中实例化存储库吗?或者我能做到

为什么不直接从视图中使用存储库呢

因为您违反了MVC设计模式。视图的职责不是获取数据。它是为了显示从控制器以视图模型的形式传递给它的数据。就这么简单

您可以在视图中调用存储库或任何您喜欢的东西,但不要再使用asp.net-mvc标记您的问题,因为您不再使用任何mvc。我的意思是,你可以做任何你喜欢的事情——如果你愿意,你甚至可以在你的视图中编写SQL查询


但是MVC设计模式的全部要点是将数据检索逻辑与表示逻辑分开。

问题是您的
视图中不应该有任何逻辑,因为这不是
MVC
方法

MVC是独立的关注点


因此,您应该创建视图模型,其中包含视图所需的所有数据。

我的主要反对意见是分离关注点。一旦你开始从你的视图中点击数据库,你的“视图”就不再只是一个视图了。在数据访问和视图之间有一个清晰的分隔非常方便


为什么关注点的分离很重要?这使得使用由这些干净分离组成的系统更容易。当您需要调整检索到的数据时,您永远不需要对视图大惊小怪。只要视图得到正确的值,它就会正确地显示它。同样,如果您想更改值的显示方式,可以修改视图,而不会损坏数据。

MVC模式的一个目的是提供一种适合各种常见编程情况的结构。要简化:

  • 模型:描述应用程序的形状,即特定于业务的软件部分
  • 视图:向用户显示数据并将用户事件传输到服务器
  • 控制器:充当视图和模型之间的中间人
你的建议“有效”,从某种意义上说,它可以在你想要的页面上获取数据。在短期内,它似乎可以节省您的时间和精力,因为您不必为控制器、可视包等烦恼

然而,您正在以一种可能会在以后后悔的方式打破MVC结构。例如,假设几周后,你的老板来找你说,“嘿,你知道你添加的显示实体列表的页面吗?我们需要对它进行过滤和排序。我昨天需要它。”

现在,您面临着一个选择:我是将此过滤逻辑添加到我的视图页面并在截止日期前完成,还是花时间将数据访问代码移动到控制器并重新编辑视图,冒着错过截止日期并破坏已在运行的功能的风险

您可能会采取简单的方法,将逻辑添加到视图中,而现在您的手上已经越来越乱。我们一直在使用VB6和Webforms应用程序,这些应用程序包含6000行代码隐藏文件。相信我,你不会想去的

另一个问题是,编程社区很好地理解MVC结构。如果有其他人出现并试图编写您的代码,您偏离了传统的方法,这会使他们更加困难


MVC结构经过时间考验,性能良好。在你完全理解它的目的和它提供的好处之前,试着密切关注它。在你牢牢掌握规则之前,打破规则不是一个好主意。

但我使用的是MVC!(我有模型、视图和控制器..还有dll;-))它为我节省了每天的工作时间,如果这样做,我节省了更多的时间,即使违反了模式,而且它没有安全隐患或任何其他我看不到的问题。。为什么不呢?只有模式?@Peto,哦,不,如果你开始在视图中调用存储库,你就错过了MVC的全部要点。我的意思是我不会说服你们:正如我在回答中所说的,你们甚至可以在一个叫做ASP.NET MVC应用程序的视图中编写SQL查询。如果您认为这是更好的,并且您觉得更有效率,然后对您有好处,请放心继续并在您的项目中实施它。我只是想指出正确的方法是什么,这样其他人在将来可能会有同样的问题,并偶然发现这个问题,就不会犯和你一样的错误。
foreach(thing in Model){
    @thing.Name : 
        @thing.related.entities.where(condition1).Count()
        @thing.related.entities.where(condition2).Count()
        @thing.related.entities.where(condition3).Count()
}
function GetCountofRelatedEntities(relatedID,condition){
    return db.entities.where(relatedID==relatedID && condition).count()
}
@repo=new ThingRepository()
foreach(thing in Model){
    @thing.Name : 
        @repo.GetCountofRelatedEntities(thing.relatedID,condition1)
        @repo.GetCountofRelatedEntities(thing.relatedID,condition1)
        @repo.GetCountofRelatedEntities(thing.relatedID,condition1)
}