Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LINQ To Entities + Include + Anonymous type issue

Consider:

Class Client

Class Project

Class Ticket

Class Reply

Clients have a sub collection of projects, projects have a sub collection of tickets and tickets have a sub collection of replies.

var data = ctx.Set<Ticket>().Include(p => p.Client).
Select(p => new { Ticket = p, LastReplyDate = p.Replies.Max(q => q.DateCreated)});

Doesn't work. Neither project nor client are loaded when selecting data this way.

I know how to make it work. My question is why doesn't it work like this?

like image 888
Jeroen Avatar asked Aug 23 '11 21:08

Jeroen


People also ask

Do anonymous types work with Linq?

You are allowed to use an anonymous type in LINQ. In LINQ, select clause generates anonymous type so that in a query you can include properties that are not defined in the class.

Which is correct about LINQ to Entities?

LINQ to Entities provides Language-Integrated Query (LINQ) support that enables developers to write queries against the Entity Framework conceptual model using Visual Basic or Visual C#. Queries against the Entity Framework are represented by command tree queries, which execute against the object context.

What is Anonymous type in LINQ?

Anonymous types provide a convenient way to encapsulate a set of read-only properties in an object without having to explicitly define a type first. If you write a query that creates an object of an anonymous type in the select clause, the query returns an IEnumerable of the type.


2 Answers

Because Include works only if you select entities directly. Once you do the projection Include is ignored. I will not tell you why but it simply works this way.

like image 196
Ladislav Mrnka Avatar answered Oct 19 '22 04:10

Ladislav Mrnka


As Ladislav mentioned, Include only works if you select the Ticket entity directly. Since you're projecting other information out, the Include gets ignored.

This should provide a good work-around:

var data = ctx.Set<Ticket>()
    .Select(p => new 
         { 
             Ticket = p, 
             Clients = p.Client,
             LastReplyDate = p.Replies.Max(q => q.DateCreated)
         });

First of all, each Ticket's Clients will be accessible directly from the Clients property on the anonymous type. Furthermore, Entity Framework should be smart enough to recognize that you have pulled out the entire Client collection for each Ticket, so calling .Ticket.Client should work as well.

like image 44
StriplingWarrior Avatar answered Oct 19 '22 06:10

StriplingWarrior