2013-07-10 5 views
2

다음에 my own question 다음에 나는 Expression<Func<T, object>>을 내 메서드에 전달하여 동일한 서비스와 동일한 메서드를 호출해야합니다. 여기Expression <Func <T, object>>

IList<T> List(params Expression<Func<T, object>>[] includeProperties); 

코드는 내가 지금 가지고 있습니다 : 다음은 방법의 정의는

//Get generic type 
    var entityRelationType = typeof(Applicant).Assembly.GetType(string.Format("Permet.BackEnd.ETL.Domain.Models.{0}", tableRelation.RelationEntityName)); 

    //create service that will receive the generic type 
    var definitionIService = typeof(IService<>).MakeGenericType(entityRelationType); 

    //instantiate the service using Unity (todo: fix singleton) 
    var serviceInstance = UnitySingleton.Container.Resolve(definitionIService, ""); 

    //create the argument for the method that we invoke 
    var paramsType = 
      typeof(Expression<>).MakeGenericType(typeof(Func<,>) 
      .MakeGenericType(entityRelationType, typeof(object))).MakeArrayType(); 


#region Get Dynamic Data 
    ParameterExpression relationParameter = Expression.Parameter(entityRelationType, ""); 

    //build the parameter that we want to pass to the method (Expression<Func<T, object>> 
    var include = 
     Expression.Lambda(
        Expression.Property(relationParameter, tableRelation.NaviguationProprietyName), 
        relationParameter 
        ); 

dynamic datas = constructedIService 
          .GetMethod("List", new Type[] { paramsType }).Invoke(serviceInstance, new object[] { include }); 

(가) 성공적으로 포함 나는 것 믿고 내 람다 식 (Param_0 => Param_0.Groupings) 만듭니다 내 Expression<Func<T, object>>. 유형의

객체 'System.Linq.Expressions.Expression 1[System.Func 2 Permet.BackEnd.ETL.Domain.Models.CLLI, 시스템 : Param_0.Groupings가 실제로 IList의이기 때문에, 나는 예외를 얻을. Collections.Generic.IList 1[Permet.BackEnd.ETL.Domain.Models.Grouping]]]' cannot be converted to type 'System.Linq.Expressions.Expression 1 [System.Func`2 [Permet.BackEnd.ETL.Domain.Models.CLLI, System.Object]] [] '. 기본적으로 내 방법 내 Expression<Func<CLLI, IList<Grouping>>> 수 없습니다 사용이 Expression<Func<CLLI, object>>을 기대하는 것을 의미한다

.

실제로 직접 일을 내 서비스를 호출하는 경우 : 그것은 작동

IService<CLLI> clliService = new Service<CLLI>(); 
clliService.List(clli => clli.Groupings); 

.

어떻게이 문제를 해결할 수 있습니까? IList가 객체가 아닌가?

답변

1

문제는 Expression<T> 당신이 Expression<T>Expression<U>에 할당 될 수 있다는 것을 의미하지는 않습니다, U를 입력 할당 할 수있는 유형 T이 때문에 경우에도 불변 것입니다. 귀하의 경우 TFunc<CLI, IList<Grouping>>이고 UFunc<CLLI, object>입니다.

내가 유일한 해결책은 object에 결과 캐스트 내부 표현에 위임하고 Expression<Func<T, object>>에 주어진 식을 래핑하는 함수를 만드는 것입니다 생각 : 래퍼 다음

public static Expression<Func<T, object>> ConvertResult<T, TOut>(Expression<Func<T, TOut>> expr) 
{ 
    var paramExpr = Expression.Parameter(typeof(T)); 
    var invokeExpr = Expression.Invoke(expr, paramExpr); 
    var castExpr = Expression.Convert(invokeExpr, typeof(object)); 

    return Expression.Lambda<Func<T, object>>(castExpr, paramExpr); 
} 
+0

을, 나는 빠른 테스트했다 , params가 배열이고 하나의 arg를 전달한다는 사실이 문제인 것처럼 보입니다. 당신이 말하는 것은 의미가 있습니다. 그러나 수동으로 호출 할 수는 있지만 왜 리플렉션을 사용하지 않는지 이해하지 못합니다. –

+0

래퍼가 작동하는 동안 호출 한 메서드로 이동하는 동안 람다식이 변환됩니다. 이 모든 것은 리플렉션을 사용하므로 랩퍼가 LambdaExpression을 대신 받도록 변환했습니다. 람다 식은 문제를 일으키는 "Param_0 => Param_0.Groupings"에서 "Param_0 => Convert (Invoke (Param_1 => Param_1.Groupings, Param_0))"로 이동합니다. –

관련 문제