System.Data.Entity.Core.Objects.ObjectQuery' 不包含 'EntitySet' 的定义

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

我只是分享这个,因为它让我发疯了一段时间,所以,张贴问题和答案以防万一有人遇到同样的情况。

我在我的一个项目中使用反射从泛型类型中获取值。 问题不在于泛型 Type 方法调用,而是实际的 return 值本身就是泛型类型。

因为我事先不知道泛型类型参数,所以我无法在 returned 对象上使用如下解决方案:

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

所以,我所做的是,使用动态类型,并在 returned 对象上调用 属性 名称。

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;

现在,在我决定将代码复制到另一个解决方案之前,它工作得很好,我正在为 Entity Framework (EntityExtensions) 创建一个开源扩展库。

在以前的解决方案中工作正常的同一行代码,在新解决方案中不再工作!!!它报告: System.Data.Entity.Core.Objects.ObjectQuery' 不包含 'EntitySet'

的定义

让我发疯的是,我能够在调试器中查看实际的 属性! 那里有一个同名的 属性,但它只是抛出一个关于在动态对象上没有这个 属性 的异常!

为了清楚起见,我将答案写为答案而不是此处。

我花了很长时间比较这两个项目,确保它们使用相同的 .Net 版本、相同的库、相同的一切;而且它们完全相同!

最后,我在直接 window 中擦掉了两者的类型定义,并开始比较它们,那时我注意到有一个区别:

IsVisible: true

这让我想到了泛型类型参数,所以我比较了两个项目,结果...原来新项目 class 设置为私有,而旧项目 class 设置为 public.

这使得反射无法读取正确的通用 return 类型,而 Visual studio 调试器能够读取。

因此,解决方案只是将类型从 private 更改为 public(我在这种情况下能够做到这一点)并且一切都很顺利。

如果遇到同样奇怪的情况,我希望这可以节省一些时间。