Skip and Take: An efficient approach to OFFSET LIMIT in EF 4.1?
The reason it's happening is the call to First, which is causing the Blog
object to be materialized. Any further traversal requires more queries.
Try db.Blogs.Take(1).SelectMany(b => b.Posts).Skip(10).Take(5).ToList();
instead to do it in one query. You probably want to add some sort of ordering of blogs before the .Take(1)
, to ensure a deterministic result.
Edit You actually have to use OrderBy before Skip (otherwise LINQ to Entities will throw an exception), which makes it something like:
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
As he suggests in his post, you could use EQL to perform this query instead. Something like:
// Create a query that takes two parameters.
string queryString =
@"SELECT VALUE product FROM
AdventureWorksEntities.Products AS product
order by product.ListPrice SKIP @skip LIMIT @limit";
ObjectQuery<Product> productQuery =
new ObjectQuery<Product>(queryString, context);
// Add parameters to the collection.
productQuery.Parameters.Add(new ObjectParameter("skip", 3));
productQuery.Parameters.Add(new ObjectParameter("limit", 5));
// Iterate through the collection of Contact items.
foreach (Product result in productQuery)
Console.WriteLine("ID: {0}; Name: {1}",
result.ProductID, result.Name);
Code taken from here: http://msdn.microsoft.com/en-us/library/bb738702.aspx