So found something interesting out the other day, and maybe you already knew this but I didn’t so I’m going to post about it. Don’t like it? Too bad.
One things nice about the Entity Framework is the ability to create or fill a class on the fly with the Linq query methods/language. You.. you have no idea what I’m trying to say. Fine. I’ll put it in programming speak:
someList.Select(item => new { item.Name, item.ID }) or from item in someList select new { item.Name, item.ID }
OR
someList.Select(item => new DataItemClass { Name = item.Name, ID = item.ID }) or from item in someList select new DataItemClass { Name = item.Name, ID = item.ID }
As you can see, they are two slightly different examples. One will create a list of anonymous types and the other a list of DataItemClass objects. Now that’s not really the point of this, the point is something like this:
context.Topics
.Select(topic =>
new TopicItem
{
TopicName = topic.Name ,
Creator = topic.User.UserName,
Category = topic.Category.Description
}
)
Now, here’s the thing that I assumed. When you select out a bunch of topics and you want to make sure that the one to on properties are “include”ed like thus:
topicList .Include("User") .Include("Category") .Select(item => item);
Other wise when you try to access that User property you’ll get a null reference exception. So with this I thought that when you query like I did above to fill the TopicItem object, I would get the same problem as I would if I tried just accessing the property on a hydrated Topic. In other words:
Creator = topic.User.UserName,
Would blow up mid query after all calling that property after a query would sans include. Come to find out, and I probably should have already known this, Entity Framework is just fine without having to have the Include method or any kind of join. Infact, adding the include method in the method chain:
context.Topics .Include("User") .Include("Category") .Select(topic => new TopicItem { TopicName = topic.Name , Creator = topic.User.UserName, Category = topic.Category.Description } )
Did nothing when I profiled the query. The SQL was exactly the same with or without the include. So it’s smart enough to know that if I am not actually hydrating an entire Topic object, it doesn’t need to bother with the includes. Go figure.