要在Select()查询中使用的Lambda表达式

我正在尝试构建一个lambda表达式,包含两个赋值(如下图所示),然后我可以传递给Queryable.Select()方法。

我试图将一个字符串变量传递给一个方法,然后使用该变量来构建lambda表达式,以便我可以在LINQ Select查询中使用它。

我的理由是我有一个包含许多列名的SQL Server数据源,我正在创建一个图表应用程序,允许用户通过输入列名来选择他们想要查看的实际数据列。我的图表的y轴,x轴始终是DateTime。 因此,他们基本上可以根据DateTime值选择他们绘制的数据(它是数据仓库类型的应用程序)。

例如,我有一个类来存储检索到的数据,因此用作以下图表来源:

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

我(纯实验)使用String值为Where子句构建了一个表达式树,并且工作正常:

 public void GetData(String yAxis) { using (DataClasses1DataContext db = new DataClasses1DataContext()) { var data = this.FunctionOne().AsQueryable(); //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>(e2, new ParameterExpression[] { pe })); } } 

但是……我已经为Select语句尝试了类似的方法,但是由于我需要Select()来填充AnalysisChartSource类的X和Y值,所以无法使它工作,如下所示:

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

我怎么能建立这样一个表达树……或者……可能更重要的是……我有一个更容易错过的方法吗?

我发现解决如何构建表达式树的最佳方法是查看C#编译器的function。 所以这是一个完整的程序:

 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> builder = z => new Foo { X = z, Y = z }; } } 

编译,在Reflector中打开结果并将优化设置为.NET 2.0。 您最终会为Main方法生成此代码:

 ParameterExpression expression2; Expression> expression = Expression.Lambda>( 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就是你所追求的。