C#通过表达式<func <tentity,object>&gt;反射获取方法在参数中

时间:2017-07-12 14:47:53

标签: c# reflection expression func

我很反思,希望你能帮助我。我发现很多类似于我的问题,但没有在我的问题上传播它。

我有一个方法:

IEnumerable<TEntity> Get<TEntity>(Expression<Func<TEntity, object>> propertyNameExpression, object propertyValue) where TEntity : NT.Base.Framework.ODL.Entity;

我通常将此方法称为: PersistentService.Get<Agent>(a => a.ID, Guid.Empty);

但是现在我只知道它在运行时我所拥有的课程。所以我有一个

Type classType;

需要知道如何使用classType调用此方法。我有一个临时解决方案,其中我使用字符串方法,但代码中的硬编码字符串不是那么好。

MethodInfo methodInfo = typeof(PersistenceService).GetMethod("Get", new Type[] { classType, typeof(string) });
var classMethod = methodInfo.MakeGenericMethod(classType);
string query = "SELECT * FROM " + classType.Name + " WHERE " + classType.Name + ".Id = '" + pg.GUID.ToString() + "'";
dynamic dEnumeration = classMethod.Invoke(PersistenceService, new object[] { query });
dynamic dEntity = Enumerable.FirstOrDefault(dEnumeration);

编辑:我尝试了以下方法,但methodInfo始终为NULL

ParameterExpression parameter = Expression.Parameter(typeof(Entity), "a");         
var delegateType = typeof(Func<,>).MakeGenericType(typeof(Entity), typeof(object));                        
var yourExpression = Expression.Lambda(delegateType, parameter, parameter);                        
MethodInfo methodInfo = typeof(PersistenceService).GetMethod("Get", new Type[] { yourExpression.GetType(), typeof(object) });

yourExpression.GetType()的类型是:

{Name = "Expression`1" FullName = "System.Linq.Expressions.Expression`1[[System.Func`2[[NT.Base.Framework.ODL.Entity, NT.Base.Framework.ODL, Version=0.0.0.126, Culture=neutral, PublicKeyToken=null],[System.Object, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"}    System.Type {System.RuntimeType}

所以请帮助我,如何获取并调用此方法。

1 个答案:

答案 0 :(得分:1)

我自己得到了它:

ParameterExpression parameter = Expression.Parameter(classType, "a");

//a.Id GUID
MemberExpression property = Expression.Property(parameter, "Id");
//a.ID as object
var newProp = Expression.TypeAs(property, typeof(object));
var delegateType = typeof(Func<,>).MakeGenericType(classType, typeof(object));
var yourExpression = Expression.Lambda(delegateType, newProp, parameter);

MethodInfo methodInfo = typeof(PersistenceService).GetMethods()
.Where(x => x.Name == "Get")
.Select(x => new { M = x, P = x.GetParameters() })
.Where(x => x.P.Length == 2
            && x.P[0].ParameterType.IsGenericType
            && x.P[0].ParameterType.GetGenericTypeDefinition() == typeof(Expression<>)                             
            && x.P[1].ParameterType == typeof(object))
.Select(x => new { x.M, A = x.P[0].ParameterType.GetGenericArguments() })
.Where(x => x.A[0].IsGenericType
            && x.A[0].GetGenericTypeDefinition() == typeof(Func<,>))
.Select(x => new { x.M, A = x.A[0].GetGenericArguments() })
.Where(x => x.A[0].IsGenericParameter
            && x.A[1] == typeof(object))
.Select(x => x.M)
.SingleOrDefault();

if(methodInfo != null)
{
    MethodInfo method = methodInfo.MakeGenericMethod(classType);
    dynamic dEnumeration = method.Invoke(PersistenceService, new object[] { yourExpression, pg.GUID });
    dynamic dEntity = Enumerable.FirstOrDefault(dEnumeration);
    ...