我开始使用存储库模式来访问数据,Entity Framework和LINQ作为非测试存储库实现的基础。大多数示例在调用返回N个记录而不是List<T>时返回AsQueryable()。这样做的优点是什么?
我开始使用存储库模式来访问数据,Entity Framework和LINQ作为非测试存储库实现的基础。大多数示例在调用返回N个记录而不是List<T>时返回AsQueryable()。这样做的优点是什么?
AsQueryable只是创建一个查询,也就是获取列表所需的指令。您可以稍后对查询进行进一步更改,例如添加新的Where子句,这些子句会发送到数据库层。
AsList返回一个实际的列表,其中包含所有的项目在内存中。如果您向其添加新的Where子句,则不会获得数据库提供的快速过滤功能。相反,您将获取列表中的所有信息,然后在应用程序中过滤掉不需要的内容。
因此,基本上就是等到最后一刻才做出承诺。
public GetMyEntities<T> (Func<bool,T> pred)
或public GetMyEntities<MyEntity> (Func<bool,MyEntity> pred)
,然后将其附加到查询中,如return context.MyEntities.Where(pred).ToList();
。你应该先检查它是否为空,但你明白我的意思。然后在调用时应用谓词,而不是之后:repo.GetMyEntities(x => x.ThatProperty == false)
。这可能会使非Linq2Sql兼容的方法更有可能抛出异常,但每种方法都有权衡。 - JoeBrockhausGetMyEntities<T> (Expression<Func<<bool,T>> pred)
而不是 GetMyEntities<T>(Func<bool,T> pred)
会怎样呢? - Jonathan Allen返回 IQueryable<T>
有一个优点,就是只有在你真正开始枚举结果并组合查询时才执行,你可以使用其他查询来组成查询,并仍然获得服务器端的执行。
问题在于,你无法控制此方法中数据库上下文的生命周期 - 你需要一个打开的上下文,并确保它保持打开状态直到查询被执行。然后你必须确保上下文将被处理。如果将结果作为 List<T>
、T[]
或类似的东西返回,你就会失去延迟执行和组合查询的服务器端执行,但你会获得对数据库上下文生命周期的控制。
当然,最适合的取决于实际要求。这是另一个没有单一答案的问题。
AsQueryable
是IEnumerable<T>
的扩展方法,可以做两件事情:
IEnumerable<T>
实现了IQueryable<T>
,则仅进行强制转换,不做任何操作。IEnumerable<T>
(EnumerableQuery<T>
),该虚拟实现每个方法都编译lambda并调用Enumerable扩展方法。因此,在大多数情况下,使用AsQueryable是无用的,除非您被迫将IQueryable传递给方法,而您只有IEnumerable,这是一种hack的方法。
注意:AsQueryable是hack方法,但IQueryable当然不是!
返回IQueryable<T>
将推迟查询的执行,直到实际使用其结果。 在此之前,您还可以在IQueryable<T>
上执行其他数据库查询操作;而在List
上,您通常只能执行效率较低的内存操作。
IQueryable
:这种类型的延迟执行方式被称为懒加载,所以查询会在需要时评估并访问到数据库。如果我们添加任何其他子句,它将使用带有过滤器的所需查询访问Db。IEnumerable
:是急切加载,因此记录首先将被加载到内存中,并且然后执行操作。因此,根据用例,例如在大量记录上进行分页时,我们应该使用 IQueryable<T>
,如果是短操作并且不会创建巨大的内存存储,则使用 IEnumerable
。