【发布时间】:2011-01-13 23:26:39
【问题描述】:
你怎么看?您的 DAO 是否应该返回一个 IQueryable 以在您的控制器中使用它?
【问题讨论】:
标签: c# asp.net-mvc iqueryable dao
你怎么看?您的 DAO 是否应该返回一个 IQueryable 以在您的控制器中使用它?
【问题讨论】:
标签: c# asp.net-mvc iqueryable dao
没有。您的控制器根本不应该处理任何复杂的逻辑。保持苗条;模型(不是 DAO)应该把它需要传递给视图的所有东西交给控制器。
在 Controller 类中看到查询(甚至可查询)我认为是代码异味。
【讨论】:
IQueryable 周围踢球或对数据库有任何了解如何?它完全打破了领域模型提供的封装。 (你确实有一个领域模型,对吧?)
目前听起来很有吸引力,但是really isn't。
【讨论】:
我喜欢将 IQueryable 传递给我的控制器,因为在我的应用开发的整个生命周期中,我不必在每个 DAO 方法和接口中创建蹩脚的分页和排序方法。
GetCustomersByLastname( string lastname )
迅速变成
GetCustomersByLastname( string lastname, string sortcolumn, int pagesize, int page )
一次又一次,一次又一次。擦!
使用 IQueryable,您可以以正交方式实现分页和排序,例如利用 IPagedList 项目。返回 IQueryable 还可以让您轻松访问总对象 .Count() ,而不会对您的数据层产生更多反常。
@Robert 的 IQueryable 等于胖控制器的参数非常不稳定。 Fat 控制器类似于过去臃肿的 .aspx.cs 页面。如果您所做的只是连接到您的 DAL,然后将结果从您的查询技术中获得“肥胖”,那么您可以通过在单个类中塞入大量逻辑来获得它。除非您开始在内部滚动日志记录、通知和其他正交关注点,否则您不会因为您的数据访问方法而获得胖控制器。
public ActionResult Detail( string searchTerm )
{
var model = MyDAL.MyObjects( searchTerm );
}
对比:
public ActionResult Detail( string searchTerm )
{
var model = MyDAL.MyObjects.Where( x => x.Name == searchTerm );
}
我看不出有什么明显的区别。
@Mark Seemann 的回答同样不稳定。当然,您可以在项目中间更改整个数据层,但无论您多么抽象,这都将是一场复杂的灾难。他使用的示例是从 Linq2Sql 切换到 Windows Azure 的表存储。 RDBMS 到键/值存储?痛点是您的存储库实施?从 RDBMS 到 Key/Value 存储将是一些疯狂的事情,无论如何这将是可怕的。
Mark 在他的论点中还提到了领域驱动设计。那是您建筑的系统类型吗?是否有足够的“领域”而不是纯粹的 CRUD 场景使这种方法有价值?如果不是那么为什么要打扰?
无论如何,使用 LINQ 和 IQueryable 接口可以减少切换数据层的痛苦。如果您在支持 LINQ 和 IQueryableProvider(我认为这就是名称)的 ORM 之间切换,那么只有下游代码才关心该更改。您的控制器将保持与现在市场上大多数 ORM 之间的相同切换。
【讨论】:
IQueryable<T> 但仍输出域模型的IPager<T> 接口轻松完成。我使用这种方法,它只需要很少的代码,并且消除了控制器和数据库之间的任何直接交互。你的比较很奇怪;似乎您的项目缺少域模型,在这种情况下,当然没有太大区别 - 但如果您没有域模型,那么您实际上没有 MVC。
IQueryable<T> 完成的任何分页(我猜这是OrderBy 和Skip 的组合)将是低效的。虽然使用它可能更方便,但有效的分页通常需要使用原始 SQL 或存储过程,它们都不适合 IQueryable<T> 过滤器/投影。
如果您遵循“胖模型,瘦控制器”范式,那么就不会。
在Fat Controller anti-pattern 上查看此帖子。
【讨论】: