Выражение Lambda для использования в запросе 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; }
}

Я (чисто экспериментальный) построил дерево выражений для предложения Where, используя значение String, и это отлично работает:

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 () для заполнения значений X и Y класса AnalysisChartSource, например:

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

Как я могу построить такое выражение tree? € .orâ € ... возможно, больше к точке ... есть ли более простой способ, который я пропустил полностью?

Принятый ответ

Я считаю, что лучший способ разработать, как построить деревья выражений, - это посмотреть, что делает компилятор 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
Является ли этот КБ законным? Да, узнайте, почему
Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему