Search code examples
c#entity-frameworkgenericsreflectiongeneric-programming

System.Data.Entity.Core.Objects.ObjectQuery' does not contain a definition for 'EntitySet'


I'm just sharing this because it drove me crazy for a while, So, posting the question and answer just in case someone runs into the same situation.

I was using reflection in one of my projects to get a value from a generic type. The problem isn't with the generic Type method invocation, but rather that the actual return value is itself a generic type.

Since I don't know the generic type parameter in advance, I can't use solutions like below, over the returned object:

method = method.MakeGenericMethod(typeof(SomeClass));
var result = method.Invoke(service, null);

So, What I did was, using the dynamic type, and calling the property name over the returned object.

var method = octx.GetType().GetMethods().First(x => x.Name == nameof(octx.CreateObjectSet) 
&& x.DeclaringType == typeof(ObjectContext));
var generic = method.MakeGenericMethod(type);
dynamic value = generic.Invoke(octx, null);// => This is the generic typed return value.
// below, Using dynamic will work, with the pitfal of no compiler checks
EntitySet set = value.EntitySet;

Now, That was working perfectly fine until I decided to copy the code over to another solution, where I'm creating an open source extensions library for Entity Framework (EntityExtensions).

The same line of code that works fine in the previous solution, No longer works in the new solution!!! It reports: System.Data.Entity.Core.Objects.ObjectQuery' does not contain a definition for 'EntitySet'

What drove me crazy is, I'm able to view the actual property in the debugger! A property with the same name is there, but It simply throws an exception about not having this property on the dynamic object!

I'm writing the answer as an answer instead of here just for clarity.


Solution

  • I took quite a while comparing both projects, ensuring they use the same .Net version, same libraries, same everything; and they were identical!

    Eventually, I blotted the Type definition in the immediate window for both, and started comparing them, That's when I noticed that there's a single difference:

    IsVisible: true
    

    That got me to think about the generic type parameter, so I compared both projects, and ... It turned out that the new project class was set to private, while the old project class was set to public.

    That made reflection unable to read the correct generic return type, while Visual studio debugger is able to do it.

    So, the solution was simply to change the type from private to public (Which I was able to do in this case) and everything worked like a charm.

    I hope this saves someone a bit of time, if encountered the same weird situation.