0

I have the following grouping type after a big query:

    IQueryable<IGrouping<Type1, IGrouping<Type2, Type3>> result;
    var executedQuery = result
       .Include(a => a.Select(b => b.Select(c => c.Type3Property)))
       .ToList();

I've tried with SelectMany too but I always get the following error:

An exception of type 'System.ArgumentException' occurred in EntityFramework.dll but was not handled in user code

Additional information: The Include path expression must refer to a navigation property defined on the type. Use dotted paths for reference navigation properties and the Select operator for collection navigation properties.

I can't use Include in the query because it doesn't work before the grouping.

When I searched for this, everyone seems to get Select to work just fine with collections, what is wrong in my case?

  • this form of select statements does seem weird indeed. however, it says the property is no navigation property. is the entity properly configured? – DevilSuichiro Sep 10 '15 at 19:56
  • Yes it is, it was automatically generated by EF from database. The property is virtual, if I don't use grouping, and select only the Type3 entity, Include works just fine. – Valar Morghulis Sep 11 '15 at 14:16

2 Answers2

0

Includes should always be convertible to the string overload Include("PropertyX"). That means that the member expression of the lambda expression in the Select statement must contain a property of the addressed type. For instance:

context.Companies.Include(c => c.Employees);

Here, Employees is a navigation property defined on the type Company. The only thing EF does is get the member expression c.Employees and then internally executes the Include statement accepting a string argument.

Now you'll understand that doesn't work with your lambda expression:

b => b.Select(c => c.Type3Property))

It doesn't contain a property, but a subsequent Select statement, let alone a navigation property.

So you can only use Include directly on an IQueryable<TEntity> (where, obviously, TEntity is a type in the EF class model). And, since you have groupings here, Includes are ]ignored if the query shape changes after they were applied](Why doesn't Include have any effect?). I think in your case this means you can't even use Include.

Side-note: in my own code I always go to great lengths to avoid abuse. Like, "we have this property X, let's also use it as a signal that ..." whatever. And a tricky dependency and a source of side-effects is introduced. I can understand that EF decided to abuse lambda expressions for a compile-time checkable Include overload, but it has caused an incredible amount of confusion. Only 1% of everything you can do with lambdas is allowed. The other 99% compiles but throws runtime exceptions.

Community
  • 1
  • 1
Gert Arnold
  • 105,341
  • 31
  • 202
  • 291
  • Thank you, this does make sens actually. Select is only used on navigation property collections. And I agree with you, it's really confusing when things compiles and throw exceptions on runtime, most of the time, for things that used to work for memory operations. This happens too often with EF. – Valar Morghulis Sep 12 '15 at 10:41
0

As a solution for my problem, I selected the properties of Type3 explicitly on the query in an anonymous object:

result.Select(g => new
        {
            Key = g.Key,
            Value = g.SelectMany(e => e.Select(x=> new
            {
                RootObject = x,
                Child1= x.prop1,
                Childe2 = x.prop2
            }))
        }).ToList();

This actually loads the children, even if I only use the root object. It's not pretty but it solved my problem.