In my post about rewriting Brad Abram’s MVC + Entity Framework example in VB, I pointed out a better way to query a collection of objects and return their entity references (eg, query products and bring along the category information) without writing a scary query filled with references, checks for nulls, etc.
But there was something bothering me about the query.
I went from this (Brad’s)
List<Product> products =TheProducts.Where(c => c.Category.CategoryName == category).ToList();//prepare the view by explicitly loading the categoriesproducts.FindAll(p => p.Category == null).ForEach(p => p.CategoryReference.Load());
var _prod = Northwind.Categories.
Where(c => c.CategoryName == id).
OrderBy(c => c.CategoryName).
Select(c => c.Products).
Which gives the same effect of ending up with a set of products and being able to drill into product.category.categoryname, etc.
But that query represents something that Entity Framework is not supposed to do, and I asked Danny Simmons about it.
Entity Framework will not perform actions that you did not request. I selected only products in my projection, yet I also got back categories. It was convenient, but it was against the promise of EF. I didn’t ask for categories.
In the end, a bug was filed, because indeed, that shouldn’t be happening.
However, it’s still VERY easy to explicitly tell EF to bring along a collection (eg if I query categories I can say “and give me those products while your at it) or an entity ref (query products and ask for the category) by using Include.
Here’s the same query for the MVC view even simpler.
var _products = Northwind.Products.Include(“Category”).
Where(p => p.Category.CategoryID == 1).ToList();
Sign up for my newsletter so you don't miss my conference & Pluralsight course announcements!
4 thoughts on “Clever LINQ to Entities query trick? Or is it a bug?”
I also wondered about the query I used to return Orders that also can return Customer info (although I only used the Order info for the particular app I built):var query = ctxNwind.Customers.Where(cust => cust.CustomerID == customerIDTextBox.Text).Select(c => c.Orders.Select(o => o)).FirstOrDefault().OrderByDescending(o => o.OrderDate);orderBindingSource.DataSource = query.ToList();The above came from an LINQ to Entities Sample Queries example.I changed the query to a version of your more conventional style;var query = ctxNwind.Orders.Include("Customers").Where(o => o.Customers.CustomerID == customerIDTextBox.Text).OrderByDescending(o => o.OrderDate);orderBindingSource.DataSource = query.ToList();It gave the same result as the above, but took 65% longer to execute! (Average 105 ms. vs. 63 shown at http://oakleafblog.blogspot.com/2008/01/linq-and-entity-framework-posts-for_29.html). Very strange.–rj
Julie,I spent a bit more time cleaning up the performance timing and found the original query’s performance was about 30% (rather than 60%) better on my test machine. The details are at oakleafblog.blogspot.com/…/entity-sql-quer
One question:I’ve been working with LINQ to SQL.I see the EDM is going to use the same context and LINQ statements?Is that a true statement?One of the problems I have with LINQ to SQL is the way ‘attach’ is implementeddoes EDM use the same or does it have a different way to handle disconnected data?Thanks for the post
Hi Steve. They both have contexts which work in a relatively similar way, though LINQ to SQL’s is a System.Data.Linq.DataContext and EF’s is System.Data.Objects.ObjectContext.The loss of change tracking is a huge issue with LINQ to SQL and Entity Framework too. I have written a LOT of posts on this – with workarounds. Danny Simmons (blogs.msdn.com/dsimmons) has as well and even has been experimenting with an Entity State bag to possibly solve the problem. The context (datacontext and objectcontext) keep track of all of the state for the entities vs. what many of us are used to with datasets or other ORMs where the state is self-contained by the object. There are a lot of reasons for this, but the big downside is overcoming the problem.One thing however, is that there are definitely more helper tools for attaching (especially if you have an object graph that is more than one object deep) in Entity Framework because they are still finishing up V1 whereas LINQ to SQL is what it is until we get some type of update. I wonder if there will be anything in SP1?