2017-07-12 4 views
0

Je suis novice dans la réflexion et j'espère que vous pourrez m'aider. Je trouve beaucoup de questions similaires à la mienne mais ne la transmet pas sur mon problème.C# Get Méthode par réflexion avec Expression <Func <TEntity, objet >> dans le paramètre

J'ai une méthode:

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

J'appelle normalement cette méthode comme ceci: PersistentService.Get<Agent>(a => a.ID, Guid.Empty);

Mais maintenant, je sais seulement au moment de l'exécution qui classe j'ai. J'ai donc un

Type classType; 

Et besoin de savoir comment appeler cette méthode avec le classType. J'ai une solution temporaire, où je prends la méthode avec une chaîne mais les chaînes codées en dur dans le code ne sont pas si belles.

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); 

Edit: j'ai essayé ce qui suit, mais METHODINFO est toujours 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) }); 

Le type de yourExpression.GetType() est:

{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} 

Alors s'il vous plaît aidez-moi, comment obtenir et invoquez cette méthode.

+0

Vous devez utiliser les API 'Expression' pour construire un arbre d'expression. – SLaks

+0

J'ai édité la question, ce que j'ai essayé mais cela ne résout pas mon problème. – Oworo

Répondre

1

Je l'ai par ma propre:

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); 
    ...