为什么使用AsQueryable()而不是List()?

Kei*_*ler 55 c# linq iqueryable repository

我正在使用存储库模式进行数据访问,实体框架LINQ作为非测试存储库实现的基础.我看到的大多数样本在调用返回N个记录而不是List <T>时返回AsQueryable().这样做有什么好处?

Jon*_*len 88

AsQueryable只是创建一个查询,获取列表所需的指令.您可以稍后对查询进行进一步更改,例如添加新的Where子句,这些子句一直发送到数据库级别.

AsList返回包含内存中所有项的实际列表.如果您添加一个新的Where cluse,则不会获得数据库提供的快速过滤.而是获取列表中的所有信息,然后过滤掉应用程序中不需要的内容.

所以基本上它归结为等到最后可能的妈妈才能做出承诺.

  • 另一点:如果你返回一个IQueryable,你必须找到一个好方法来确保1.)上下文打开直到执行查询和2.)上下文将正确处理.返回列表的优点是可以控制方法中上下文的生命周期.什么更适合取决于实际要求. (14认同)
  • 同意,但请记住,除了"快速过滤"之外,还有通过网络发送所有信息的热门话题. (7认同)
  • 同样,这不是唯一的方法,因为您可以接收要应用的过滤器,而不是返回可以过滤的内容。如果您后来从使用db转移到其他东西(例如Web服务或其他任何东西),则第一个更易于使用。 (2认同)
  • WRT @eglasius您可以很容易地将谓词作为存储库方法的参数,例如`public GetMyEntities &lt;T&gt;(Func &lt;bool,T&gt; pred)`或`public GetMyEntities &lt;MyEntity&gt;(Func &lt;bool,MyEntity&gt; pred)然后将其附加到查询中,例如return context.MyEntities.Where(pred).ToList();。您应该先检查它是否不为null,但是您知道了。然后,在使用它时,可以在调用中应用谓词,而不是在谓词之后:`repo.GetMyEntities(x =&gt; x.ThatProperty == false)'。这可以使非Linq2Sql兼容的方法更有可能抛出异常,但是每个方法都有权衡 (2认同)

Dan*_*ner 23

返回IQueryable<T>的优点是执行是defferer,直到你真正开始枚举结果,你可以用其他查询组成查询,仍然得到服务器端执行.

问题是您无法在此方法中控制数据库上下文的生命周期 - 您需要一个开放的上下文,并且必须确保它在查询执行之前保持打开状态.然后你必须确保处理上下文.如果返回的结果为List<T>,T[]或者类似的东西,你失去递延执行和组成查询的服务器端执行,但你赢得控制权,数据库上下文的寿命.

当然,最合适的是取决于实际要求.这是另一个没有一个真理的问题.


Olm*_*lmo 11

AsQueryable是一种扩展方法IEnumerable<T>,可以做两件事:

  • 如果IEnumerable<T>工具IQueryable<T>只是施放,什么都不做.
  • 否则创建一个'fake' IEnumerable<T>(EnumerableQuery<T>),它实现编译lambda并调用Enumerable扩展方法的每个方法.

所以在大多数情况下使用AsQueryable是没用的,除非你被迫将IQueryable传递给一个方法,而你有一个IEnumerable,这是一个黑客.

注意:AsQueryable是一个黑客,IQueryable当然不是!

  • AsQueryable并非无用,因为你声明"强制传递为IQueryable"的用例是有效的,它允许你使用IQueryable提供的东西,而且它不仅仅是IEnumerable.我不认为它是一个黑客,它有它的用途,例如见:http://wcf.codeplex.com/wikipage?title = Getting%20started:%20Building%20a%20simple%20web%20api.但我想你想说的是它不能用于更深入地影响可枚举数据的生成方式(例如优化查询),它只能在获取/创建的内容之上工作. (2认同)