4

I am making a website on asp.net MVC and I am using a repository interface to use repository in memory and using database.

I have all my relationships fixed up, what I mean is for example when I have one contact than he have addresses, so.. when I add one address to this contact automatically fixup the relashionship for address.contact points to the contact, and I leave the properties virtual for entity framework create the proxies then using database repository.

My question starts here:

I have one query like this:

return query.Where(c => c.UserID == clientId)
                         .Include(c => c.AssignedProjects)
                         .Select(c => new UserDetailsData<Client>
                         {
                             User = c,
                             IssuesCount = c.IssuesReported.Count()
                         }).Single();

that uses include. If I remove the Select assignedProjects will contain the Projects for this client, but when I include Select AssignedProjects is null and anonymous object is fine but.. user don't contain any AssignedProjects.

In memory I can do that, but using EF I cannot.

The final graph that I want is.. The user with clientID having collection AssignedProjects with his projects and creates anonymous object with User (with the collection) and IssuesCount passing to a view to show the AssignedProjects, The User information and the number of issues that client reported..

Anyone know how I can resolve this?

tereško
  • 58,060
  • 25
  • 98
  • 150
gds03
  • 1,349
  • 3
  • 18
  • 39
  • Honestly this could be entirely wrong but I was passing through and thought I would give it a shot. Try working in AsQueryable() perhaps between include and select. Let me know if that does anything for you :P. – Alec Jul 05 '11 at 20:58

2 Answers2

0

Include (eager loading) does not work with Select (projection) as far as generating a store expression using Entity Framework.

You can find more information If I select from an IQueryable then the Include is lost and you can see a work around there as well.

I am not sure if the work around that was listed will work though in your case as your projection has multiple returns (rather than an expected object).

Since you stated that the final graph is what you want in addition to performing the actual count, why not turn this into:

var user = query.Where(c => c.UserID == clientId)
    .Include(c => c.AssignedProjects)
    .Include(c => c.IssuesReported)
    .Single();

var userDetailsData = new UserDetailsData<Client>()
{
    User = user,
    IssuesCount = user.IssuesReported.Count(),
};
Community
  • 1
  • 1
jwendl
  • 942
  • 7
  • 13
  • Thanks for the reply. Yes first i thought about that solution but i just really want the count of the issues, i dont want any issues loaded into memory just for sake of count them ;) – gds03 Jul 05 '11 at 20:32
0

You can try this:

return query.Where(c => c.UserID == clientId)
            .Select(c => new UserDetailsData<Client>
            {
                User = c,
                AssignedProjects = c.AssignedProjects,
                IssuesCount = c.IssuesReported.Count()
            }).Single();

Although you are not really interested in the AssignedProjects property of the type you project into it will populate the User.AssignedProjects property too. This leverages "relationship span", a feature in EF which automatically builds up navigation properties of objects loaded into the context.

Be aware that this really relies on the fact that you load the objects into the context. If you disable tracking - for instance by using AsNoTracking() in your query - it doesn't work anymore.

Slauma
  • 175,098
  • 59
  • 401
  • 420
  • This code works just fine, but i need always be worried about this situations (projecting with include) and on my views i cannot use collection pointer to go throught another entities, because this issue.. But until now is the better solution. – gds03 Jul 05 '11 at 21:31