2016-11-21 78 views
3

有效我有以下两种实体框架的包括如下的方法:获取方法的MethodInfo的 - 该操作仅在泛型类型

public static IIncludableQueryable<TEntity, TProperty> Include<TEntity, TProperty>(
    [NotNullAttribute] this IQueryable<TEntity> source, 
    [NotNullAttribute] Expression<Func<TEntity, TProperty>> navigationPropertyPath) 
    where TEntity : class; 

public static IQueryable<TEntity> Include<TEntity>(
    [NotNullAttribute] this IQueryable<TEntity> source, 
    [NotNullAttribute][NotParameterized] string navigationPropertyPath) 
    where TEntity : class; 

我需要得到MethodInfo的两种方法。这是第一个我用:

MethodInfo include1 = typeof(EntityFrameworkQueryableExtensions) 
    .GetMethods().First(x => x.Name == "Include" && x.GetParameters() 
    .Select(y => y.ParameterType.GetGenericTypeDefinition()) 
    .SequenceEqual(new[] { typeof(IQueryable<>), typeof(Expression<>) })); 

这个工作,但是当我尝试使用,以获得第二下列操作之一:

MethodInfo include2 = typeof(EntityFrameworkQueryableExtensions) 
    .GetMethods().First(x => x.Name == "Include" && x.GetParameters() 
    .Select(y => y.ParameterType.GetGenericTypeDefinition()) 
    .SequenceEqual(new[] { typeof(IQueryable<>), typeof(String) })); 

我得到的错误:

This operation is only valid on generic types

什么时我错过了?

+0

'string navigationPropertyPath'是通用的吗? – CodeCaster

+0

不,这只是一个字符串...我在上面添加了方法签名。 –

+0

'ParameterType.GetGenericTypeDefinition()'如何返回'typeof(String)'? –

回答

4

好的,让我们分开。首先你想得到方法的所有过载:

var overloads = typeof(EntityFrameworkQueryableExtensions) 
    .GetMethods() 
    .Where(method => method.Name == "Include"); 

然后你想匹配参数类型对特定的序列,所以你可以选择适当的过载。你的代码的问题是你假设所有的参数都是泛型类型,当不是这种情况。您可以使用三元条款通用和非通用参数类型来区分:

var include2 = overloads.Where(method => method 
    .GetParameters() 
    .Select(param => param.ParameterType.IsGenericType ? param.ParameterType.GetGenericTypeDefinition() : param.ParameterType) 
    .SequenceEqual(new[] { typeof(IQueryable<>), typeof(string) })); 

这产生了第二个重载,符合市场预期,并没有抱怨你试图从第二个参数上typeof(string)调用GetGenericTypeDefinition

+0

首先,我认为你的意思是IsGenericParameter而不是IsGenericType。其次,您没有返回MethodInfos,而是返回类型。所以include2是一个类型列表。最后,我终于没有收到物品。任何想法为什么? –

+0

@MiguelMoura不,我的意思是'IsGenericType',而不是'IsGenericParameter'。我自己测试了它,它的工作原理,请参阅:https://gist.github.com/masaeedu/7150ee92becdad4e514dfa160da460ad。其次,我在两个片段中都返回了一个IEnumerable ',而不是'IEnumerable '。我鼓励你将代码粘贴到你的IDE中。 –

+0

@MiguelMoura也许你对缩进感到困惑,但第二个片段实际上就是你的代码,其中'Select'子句被修改为具有三元表达式。 –

相关问题