Select () 쿼리에서 사용할 람다 식

c# expression-trees lambda

문제

두 개의 배정 (아래 그림 참조)을 포함하는 람다 식을 작성하려고하는데, Queryable.Select () 메서드에 전달할 수 있습니다.

문자열 변수를 메서드에 전달한 다음 해당 변수를 사용하여 LINQ Select 쿼리에서 사용할 수 있도록 람다 식을 작성하려고합니다.

그 이유는 SQL Server 데이터 소스가 많은 열 이름을 가지고 있기 때문에 사용자가 열 이름을 입력하여 실제 데이터 열을 선택하는 차트 작성 응용 프로그램을 만드는 것입니다. 내 차트의 y 축, x 축은 항상 DateTime입니다. 따라서 DateTime 값 (데이터웨어 하우스 유형 앱)에 대해 차트로 어떤 데이터를 선택 할지를 기본적으로 선택할 수 있습니다.

예를 들어, 검색된 데이터를 저장하는 클래스가 있으므로 차트 원본으로 사용합니다.

public class AnalysisChartSource
{
    public DateTime Invoicedate { get; set; }
    public Decimal yValue { get; set; }
}

나는 순전히 experimentaly 문자열 값을 사용하여 Where 절에 대한 식 트리를 작성하고 그 잘 작동합니다.

public void GetData(String yAxis)
{
    using (DataClasses1DataContext db = new DataClasses1DataContext())
    {
        var data = this.FunctionOne().AsQueryable<AnalysisChartSource>();
        //just to get some temp data in....

        ParameterExpression pe = Expression.Parameter(typeof(AnalysisChartSource), "p");
        Expression left = Expression.MakeMemberAccess(pe,
                                                typeof(AnalysisChartSource).GetProperty(yAxis));
        Expression right = Expression.Constant((Decimal)16);
        Expression e2 = Expression.LessThan(left, right);
        Expression expNew = Expression.New(typeof(AnalysisChartSource));

        LambdaExpression le = Expression.Lambda(left, pe);

        MethodCallExpression whereCall = Expression.Call(
            typeof(Queryable), "Where", new Type[] { data.ElementType },
            data.Expression,
            Expression.Lambda<Func<AnalysisChartSource, bool>>(e2, new ParameterExpression[] { pe }));
    }
}

그러나 Select 문에 대해 비슷한 접근 방식을 시도했지만 Select ()를 사용하여 AnalysisChartSource 클래스의 X 및 Y 값을 채우려면 다음과 같이 할 수 없습니다.

.Select(c => new AnalysisChartSource 
{ Invoicedate = c.Invoicedate, yValue = c.yValue}).AsEnumerable();

어떻게 지구상에서 그러한 표현을 만들 수 있을까요? 아니면 ... 내가 더 이상 놓칠 수없는 쉬운 방법이 있을까요?

수락 된 답변

표현식 트리를 작성하는 가장 좋은 방법은 C # 컴파일러가 수행하는 작업을 확인하는 것입니다. 여기 완벽한 프로그램이 있습니다.

using System;
using System.Linq.Expressions;

public class Foo
{
    public int X { get; set; }
    public int Y { get; set; }
}

class Test
{
    static void Main()
    {
        Expression<Func<int, Foo>> builder = 
            z => new Foo { X = z, Y = z };
    }
}

그것을 컴파일하고 Reflector에서 결과를 열고 최적화를 .NET 2.0으로 설정합니다. Main 메소드에 대해 생성 된 코드로 끝난다.

ParameterExpression expression2;
Expression<Func<int, Foo>> expression = 
  Expression.Lambda<Func<int, Foo>>(
    Expression.MemberInit(
      Expression.New((ConstructorInfo) methodof(Foo..ctor), new Expression[0]),
      new MemberBinding[] { Expression.Bind((MethodInfo) methodof(Foo.set_X),
                           expression2 = Expression.Parameter(typeof(int), "z")),
                           Expression.Bind((MethodInfo) methodof(Foo.set_Y), 
                                            expression2) }
    ),
    new ParameterExpression[] { expression2 });

기본적으로, 나는 Expression.MemberInit 이 당신이 무엇인지 생각합니다.



아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.