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

时间:2017-11-12 02:23:09

标签: c# entity-framework generics reflection generic-programming

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

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

由于我事先并不知道泛型类型参数,因此我不能在返回的对象上使用如下所示的解决方案:

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

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

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'的定义

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

为了清楚起见,我把答案写成答案而不是这里。

1 个答案:

答案 0 :(得分:1)

我花了很长时间比较两个项目,确保他们使用相同的.Net版本,相同的库,同样的一切;他们是相同的!

最后,我在两个方面的立即窗口中印上了类型定义,并开始比较它们,那时我注意到有一个区别:

IsVisible: true

这让我想到了泛型类型参数,所以我比较了两个项目,并且......结果是新项目类被设置为private,而旧项目类被设置为public。

这使得反射无法读取正确的泛型返回类型,而Visual Studio调试器能够执行此操作。

所以,解决方案只是将类型从私有更改为公共(在这种情况下我能够做到),一切都像魅力一样。

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