C# ASP MVC:服务是否应该返回IQueryable';s

C# ASP MVC:服务是否应该返回IQueryable';s,c#,asp.net-mvc,iqueryable,dao,C#,Asp.net Mvc,Iqueryable,Dao,你觉得怎么样?您的DAO是否应该返回一个iquery,以便在控制器中使用它?否。您的控制器不应该处理任何复杂的逻辑。保持苗条;模型(而不是DAO)应该将需要传递到视图上的所有内容交还给控制器 在控制器类中看到查询(甚至查询)是一种我认为是代码气味的东西。 目前,它听起来很吸引人,但是 < P>如果你遵循“胖模型,瘦控制器”范式,那么No.< 请参阅上的这篇文章。我喜欢将IQueryable传递到我的控制器中,因为在我的应用程序开发的整个生命周期中,我不必在每个DAO方法和接口中创建蹩脚的分页和排

你觉得怎么样?您的DAO是否应该返回一个iquery,以便在控制器中使用它?

否。您的控制器不应该处理任何复杂的逻辑。保持苗条;模型(而不是DAO)应该将需要传递到视图上的所有内容交还给控制器


在控制器类中看到查询(甚至查询)是一种我认为是代码气味的东西。

目前,它听起来很吸引人,但是

< P>如果你遵循“胖模型,瘦控制器”范式,那么No.<
请参阅上的这篇文章。

我喜欢将IQueryable传递到我的控制器中,因为在我的应用程序开发的整个生命周期中,我不必在每个DAO方法和接口中创建蹩脚的分页和排序方法

GetCustomersByLastname( string lastname )
很快变成

GetCustomersByLastname( string lastname, string sortcolumn, int pagesize, int page )
一次又一次,一次又一次。布莱克

使用IQueryable,您可以采用正交方式实现分页和排序,例如利用IPagedList项目。返回IQueryable还可以让您轻松访问total object.Count(),而不会对数据层造成更多的扭曲

@罗伯特关于IQueryable等于fat控制器的论点非常不可靠。Fat控制器将类似于昔日臃肿的.aspx.cs页面。如果您所做的一切都是连接到DAL,然后将结果从您的DAL中发送出去,而不是从查询技术中获得“胖”,那么您可以通过将大量逻辑推到单个类中来获得它。由于您的数据访问方法,您不会得到Fat控制器,除非您开始在其中滚动日志记录、通知和其他正交关注点

public ActionResult Detail( string searchTerm )
{
    var model = MyDAL.MyObjects( searchTerm );
}
vs:

我看不出有什么明显的区别

@马克·西曼的答案同样不可靠。当然,你可以在项目中间改变整个数据层,但不管你有多抽象,这将是一场复杂的灾难。他使用的例子是从Linq2Sql切换到WindowsAzure的表存储。RDBMS到键/值存储?难点是您的存储库实现?从RDBMS到键/值存储将是一种疯狂,无论发生什么情况,都将是可怕的

Mark还在他的论点中提出了领域驱动设计。这就是你们大楼的系统类型吗。是否有足够的“领域”而非纯粹的CRUD场景使这种方法具有价值?如果没有,那为什么还要麻烦呢


使用and LINQ和IQueryable接口可以减少切换数据层的痛苦。如果您在支持LINQ和IQueryableProvider的ORM之间切换(我想这就是名称),那么只有下游代码才关心这个更改。您的控制器将保持不变,在市场上大多数的ORM之间切换。

谢谢Aaron,说得好。尽管如此,使用IQueryable还是有一些优势,比如服务的灵活性和可维护性——因为使用管道和过滤器模式DAO接口的增长会更少。你认为呢?当一个项目很年轻很小的时候,意大利面条式的代码似乎总是比较容易维护;但是,随着项目的发展,您会开始后悔没有明确区分关注点。传递IQueryable和/或使用管道和过滤器并不等于使用意大利面条代码。意大利面代码在语言或技术方面通常是不可知的。@jfar:controller类的职责是根据用户请求提供视图。如何在
IQueryable
周围闲逛,或者对数据库有任何了解,除了意大利面代码?它完全打破了域模型提供的封装。(你有一个域模型,对吗?)不,我有一个持久性模型。如果在我的回答中,两个动作方法片段之间的区别是其中一个是“干净的”,那么您对意大利面代码的标准是非常低的另一个是意大利面。如果这是为了排序和分页,那么可以使用
IPager
接口轻松实现,该接口包装
IQueryable
,但仍然输出域模型。我使用这种方法,它只需要很少的代码,并且消除了控制器和数据库之间的任何直接交互。你的比较很奇怪;似乎您的项目缺少域模型,在这种情况下,当然没有太大区别-但是如果您没有域模型,那么您就没有真正的MVC。还要注意,使用
IQueryable
完成的任何分页(我猜这是
OrderBy
Skip
的组合)这将是低效的。虽然使用它可能更方便,但有效的分页通常需要使用原始SQL或存储过程,这两种方法都不适合
IQueryable
过滤器/投影。@A尽管您的第二条评论是错误的。所有支持Linq的.Net ORM都可以使用IQueryable上的.Skip()和.Take()生成高效的分页sql。我不是,也从来不是DDD、MDD、TDD或本月最新的敏捷风格的倡导者;然而,我相信,在几乎任何应用程序中,独立于关系模型的领域模型都是很好的设计。过去我曾几次跳过这一阶段,通过高层抽象公开数据对象,但后来我对这一决定感到遗憾。就我的两分钱。:)@Aaronaught您的寻呼问题非常棘手。这篇文章读得很好,我学到了很多东西,但性能数据并不令人印象深刻。没有人会翻阅100k记录表。用户将搜索某些内容。这是“如果你有数以百万计的用户和千兆字节的数据怎么办”论点的一个变体,这是大多数系统所不具备的。我尊重你的意见,但似乎你的编码违背了你的领域将是丰富的,你的规模将是巨大的假设。Stackoverflow是用一个“贫血模型”构建的,它似乎工作正常
public ActionResult Detail( string searchTerm )
{
    var model = MyDAL.MyObjects.Where( x => x.Name == searchTerm );
}