You will probably need two queries to get the result. If you only want the first element (FirstOrDefault
) explicit loading - as you already proposed in the comments - is a good approach:
var comment = DbContext.Set<UserComment>().FirstOrDefault();
if (comment is BlogComment)
DbContext.Entry(comment as BlogComment).Reference(bc => bc.Blog).Load();
else if (comment is PhotoComment)
DbContext.Entry(comment as PhotoComment).Reference(pc => pc.Photo).Load();
If you want to load a list of UserComment
s that's not the best solution as it would require to iterate over the loaded UserComment
s and to call explicit loading for each element which will result in many queries.
For a list you can use the following approach that also will generate only two queries:
IEnumerable<UserComment> blogComments = DbContext.Set<UserComment>()
.OfType<BlogComment>()
.Include(bc => bc.Blog)
.Cast<UserComment>()
.AsEnumerable();
IEnumerable<UserComment> photoComments = DbContext.Set<UserComment>()
.OfType<PhotoComment>()
.Include(pc => pc.Photo)
.Cast<UserComment>()
.AsEnumerable();
List<UserComment> comments = blogComments.Concat(photoComments).ToList();
Because of the usage of AsEnumerable()
this will run two separate database queries and concat the results to a single collection in memory.
LINQ-to-Entities supports Cast
but for some reason it is not possible to remove the two AsEnumerable()
conversions to get only a single database query and concat the results in the database. The code would still compile but I had a runtime exception about an invalid Include
path.
I have tested with EF 4.1. It might be worth to test the query without AsEnumerable()
with EF 5.0 to see if it still fails.