在选择要使用Lambda表达式()查询 [英] Lambda Expression to be used in Select() query

查看:100
本文介绍了在选择要使用Lambda表达式()查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想建立一个lambda表达式,包含两个任务(如图所示进一步下跌),那我就可以传递给Queryable.Select()方法。

I am trying to build a lambda expression, containing two assignments (as shown further down), that I can then pass to a Queryable.Select() method.

我想一个字符串变量传递到一个方法,然后使用该变量建立起来的lambda表达式,这样我可以在LINQ Select查询使用。

I am trying to pass a string variable into a method and then use that variable to build up the lambda expression so that I can use it in a LINQ Select query.

我背后的理由是,我有很多列名的SQL Server数据源,我创建一个图表应用程序,允许用户选择,通过键入说列名,他们想要查看我的图表的y轴与x轴总是被DateTime数据的实际的列。因此,他们基本上可以选择他们绘制哪些数据对DateTime值(这是一个数据仓库类型的应用程序)。

My reasoning behind it is that I have a SQL Server datasource with many column names, I am creating a charting application that will allow the user to select, say by typing in the column name, the actual column of data they want to view in the y-axis of my chart, with the x-axis always being the DateTime. Therefore, they can essentially choose what data they chart against the DateTime value (it’s a data warehouse type app).

我有,例如,一个类来存储检索

I have, for example, a class to store the retrieved data in, and hence use as the chart source of:

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

我(纯粹experimentaly)建立了一个表达式树Where子句使用字符串值和正常工作:

I have (purely experimentaly) built an expression tree for the Where clause using the String value and that works fine:

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语句,但就是无法得到它的工作,因为我需要选择()来填充AnalysisChartSource类的X和Y值,如:

However……I have tried a similar approach for the Select statement, but just can’t get it to work as I need the Select() to populate both X and Y values of the AnalysisChartSource class, like this:

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



如何在地球上,我可以建立这样一个表达式树... ...。或者更多.possibly给点... ..是有,我已经完全错过了一个更简单的方法?

How on earth can I build such an expression tree….or….possibly more to the point…..is there an easier way that I have missed entirely?

推荐答案

我觉得最好的方式来解决如何打造表达式树是看C#编译器做了什么。所以这里有一个完整的程序:

I find that the best way to work out how to build expression trees is to see what the C# compiler does. So here's a complete program:

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



编译,打开反射的结果,并设置优化.NET 2.0。你结束了本作的主要方法生成代码:

Compile that, open the results in Reflector and set the optimisation to .NET 2.0. You end up with this generated code for the Main method:

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 是你追求的。

Basically, I think Expression.MemberInit is what you're after.

这篇关于在选择要使用Lambda表达式()查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆