2009-01-05 53 views
8

我目前在玩Asp.Net mvc框架,并且喜欢它与经典的asp.net方式相比。我正在模拟的一件事是View是否可以接受导致(间接)访问数据库?ASP.Net Mvc - 视图可以调用可能导致数据检索的函数吗?

例如,我使用控制器来填充一个自定义数据类,其中包含我认为View需要完成其工作的所有信息,但是由于我将对象传递给视图,因此它也会导致数据库读取。

一个快速的伪示例。

public interface IProduct 
{ 
    /* Some Members */ 

    /* Some Methods */ 
    decimal GetDiscount(); 
} 

public class Product : IProduct 
{ 
    public decimal GetDiscount(){ ... /* causes database access */ } 
} 

如果视图访问产品类(它被传递一个IProduct对象),它可以调用GetDiscount()而引起的数据库访问。

我在想办法来防止这种情况。目前我只为Product类提供多种接口继承。现在不用实施IProduct,而是实施IProduct和。 IProductView将列出类的成员,IProduct将包含可能导致数据库访问的方法调用。

“查看”将只了解接口到类,并不能称之为造成数据访问方法。

我对“锁定”它被传递到前视图的对象等模糊的想法,但我可以预见的副作用这样的方法巨大范围。

所以,我的问题:

  • 是否有关于这个问题的最佳做法?
  • 使用MVC的其他人如何阻止视图变得淘气并且对对象做的事情比他们应该做的更多?

回答

3

您的看法并非真正导致数据访问。该视图只是在模型接口中调用GetDiscount()方法。这是导致数据访问的型号。事实上,您可以创建另一个不会导致数据访问的IProduct实现,但不会改变视图。

模型对象做迟缓装载必然导致数据访问时的视图尝试为显示提取数据。

是否可以回归个人品味和偏好。

但是,除非您有充分的延迟加载原因,否则我宁愿将数据加载到模型对象中,然后将该“已准备好的”数据传递给要显示的视图。

+0

我想向视图提供已准备好的烘焙数据,那就是我在控制器中所做的事情(我使用构建器创建视图模型类),我(可能过早地)想要迎合将来可能需要的情境在交易中的所有数据库访问 - 例如 - 在视图中不容易控制! – Ash 2009-01-06 00:25:59

1

我正在调用的一件事是View是否可以接受导致(间接)访问数据库?

我经常问同样的问题。我们在堆栈溢出视图中的模型上访问的许多内容可能会导致隐式数据库访问。这几乎是不可避免的。很想听到别人对此的看法。

+1

MVC中的模型不是强大的领域模型。或者至少它不应该。这是一个轻量级的视图模型 - 一个零级安全的扁平DTO和其他表示对象的层次结构。您的控制器和其他服务构建视图模型;该视图简单地呈现它。 – 2009-01-07 12:28:26

0

模型不应该有一个包括数据访问方法(“行动”)。这是DAL的担忧。 YOu可以有一个存储在产品类中的折扣百分比属性,并使GetDiscount方法返回一个简单的计算,如Price *(100 - discountPercent)或类似的东西。

我从数据访问断开我的业务实体(在你的榜样产品)。这是存储库(在我的情况下)的关注。

+0

我的模型中有一些方法可以防止出现这种情况,即在允许任何其他代码触摸它之前,您只需要“填充”对象就可以不必要地执行昂贵的数据库操作。如果在这种特殊情况下,你从不使用折扣价值,但仍然可以检索它? – Ash 2009-01-06 00:18:50

+0

我也许应该补充一点,GetDiscount()可能是方法名称的错误选择,也许GetCategories()可能更适合。即与类所代表的对象直接相关的东西,但实际上并不是数据库表的一部分。 – Ash 2009-01-06 00:20:03

+0

@Ash:对于GetCategories()示例,我将使用MenuDocument对象填充我的ViewData,该对象包含呈现类别菜单所需的所有信息。 MenuDocument本身可以由ActiveRecord风格的域类填充。 – 2009-01-06 00:22:26

1

如果你让你的域对象“持续不知情”,那么你就没有这个问题。也就是说,为什么不只是有一个名为Discount的简单属性,而不是在Product类中有getDiscount?这会在从数据库加载Product类的实例时由ORM设置。

0

我在MonoRail中建立了一个站点,在那之前有时候会有方法从视图中触发数据访问。我尽量避免它,因为当它失败时,它可能以非常规和不可修复的方式失败(例如,我不能真正尝试/捕获NVelocity模板)。这完全不是世界的尽头 - 我写了很多年抽象的PHP站点,从视图访问数据库,他们仍然工作得很好,因为大部分时间,如果事情发生了,你只是重定向到一个“无论如何,什么都不起作用“ - 类型错误页面。

但是,我尽量避免它。从更广泛的意义上说,我的领域模型通常不会一直流入视图。相反,该视图呈现Document对象,这些对象只是强类型的数据转储,所有的预格式化,鞭打,压缩和纯化到视图只需要用某些循环吐出一些字符串的位置,并且if/else,将数字“4”转换为4星形图像等等。该文档通常由位于漂亮域模型前面的Web服务返回,或者它只是一个简单的结构,它在控制器中构建并传递作为ViewData的一部分。如果直接使用域对象,那么通常不会明确触发数据访问;这是由视图无权访问且域对象通常无权访问的集合式存储库处理的。

但是你不必这样做。你可能只是足够受欢迎,而不是从视图中调用那些触及数据库的方法。

相关问题