以下代码:
using (var db = new Entities()) { db.Blogs.First().Posts.Skip(10).Take(5).ToList(); }
-- statement #1 SELECT TOP ( 1 ) [c].[Id] AS [Id],[c].[Title] AS [Title],[c].[Subtitle] AS [Subtitle],[c].[AllowsComments] AS [AllowsComments],[c].[CreatedAt] AS [CreatedAt] FROM [dbo].[Blogs] AS [c] -- statement #2 SELECT [Extent1].[Id] AS [Id],[Extent1].[Title] AS [Title],[Extent1].[Text] AS [Text],[Extent1].[PostedAt] AS [PostedAt],[Extent1].[BlogId] AS [BlogId],[Extent1].[UserId] AS [UserId] FROM [dbo].[Posts] AS [Extent1] WHERE [Extent1].[BlogId] = 1 /* @EntityKeyValue1 */
(从http://ayende.com/blog/4351/nhibernate-vs-entity-framework-4-0)
NB Skip和Take没有被翻译成sql,导致从数据库加载博客的所有帖子,而不是我们需要的5.
这似乎是危险的,可怕的低效率.令人难以置信的是,什么给了?
解决方法
它发生的原因是调用
First,这导致Blog对象被实现.任何进一步的遍历都需要更多的查询.
尝试db.Blogs.Take(1).SelectMany(b => b.Posts).Skip(10).Take(5).ToList();而是在一个查询中执行.您可能想在.Take(1)之前添加一些博客排序,以确保确定性的结果.
编辑
你实际上必须在跳过之前使用OrderBy(否则LINQ to Entities会抛出异常),这样做就像:
db.Blogs.OrderBy(b => b.Id).Take(1) // Filter to a single blog (while remaining IQueryable) .SelectMany(b => b.Posts) // Select the blog's posts .OrderBy(p => p.PublishedDate).Skip(10).Take(5).ToList(); // Filter to the correct page of posts