Using a Lambda Expression to Select Different Fields from Field Names

I need to get two fields from a database table (retrieved using linq-to-sql), one field is a date-time (and is a fixed field), and the other is decimal, but the field may be different.

The table stores currency data that is processed twice a day and in different currencies, so it can have fields such as AM_USD, PM_USD, AM_EUR, etc. And I need to get data, such as a date list against PM_USD or a date against AM_EUR.

I would like to be able to call data using, for example, a lambda expression (this is a stripped-down example):

data = TableData.Select(x=>new {x.DateTimeAdded, x.[**field name as string**]}); 

I am trying to write a function to do this and I am not depressed.

The closest I managed:

 private Func<TableData, KeyValuePair<DateTime, decimal>> CreateSelect(string FieldName) { var parameterExp = Expression.Parameter(typeof(TableData), "sel"); var dateParameter = Expression.Parameter(typeof(DateTime), "DateTimeAdded"); var fieldParameter = Expression.Parameter(typeof(decimal), FieldName); ConstructorInfo constructorInfo = typeof(KeyValuePair<DateTime, decimal>).GetConstructor(new[] { typeof(DateTime), typeof(decimal) }); NewExpression constructExpression = Expression.New(constructorInfo, new ParameterExpression[] { dateParameter, fieldParameter}); var lambda = Expression.Lambda<Func<TableData, KeyValuePair<DateTime, decimal>>>( constructExpression, parameterExp); return lambda.Compile(); } 

What fails with "System.InvalidOperationException: Lambda parameter is not in scope."

I am sure that I have missed something obvious or not mistaken.

Any ideas?

Thank you

+7
c # lambda expression linq-to-sql
source share
2 answers

x.Foo is a member of x (a property or field), not a parameter:

 private Func<TableData, KeyValuePair<DateTime, decimal>> CreateSelect(string FieldName) { var parameterExp = Expression.Parameter(typeof(TableData), "sel"); var dateProp = Expression.PropertyOrField(parameterExp, "DateTimeAdded"); var fieldProp = Expression.PropertyOrField(parameterExp, FieldName); ConstructorInfo constructorInfo = typeof(KeyValuePair<DateTime, decimal>).GetConstructor(new[] { typeof(DateTime), typeof(decimal) }); NewExpression constructExpression = Expression.New(constructorInfo, new [] { dateProp, fieldProp}); var lambda = Expression.Lambda<Func<TableData, KeyValuePair<DateTime, decimal>>>( constructExpression, parameterExp); return lambda.Compile(); } 
+4
source share

From your question:

 data = TableData.Select(x=>new {x.DateTimeAdded, x.[**field name as string**]}); 

Specifying a field name in a LINQ query as a string can be done using the LINQ Dynamic Query Library .

You can use the DynamicQuery library against any LINQ data provider (including LINQ to SQL, LINQ to Objects, LINQ to XML, LINQ to Objects, LINQ to SharePoint, LINQ to TerraServer, etc.). Instead of using language operators or safe types of lambda extension methods for LINQ queries, the dynamic query library provides you with string-based extension methods that you can pass any string expression into.

And by the way, I even thought that question is not quite identical, almost the same.

+3
source share

All Articles