2010-11-18 2 views
7

Мне нужно получить два поля из таблицы базы данных (с помощью linq-to-sql), одно поле - это дата-время (и это фиксированное поле), а другое всегда десятичное, но поле может быть другим.Использование выражения Лямбда для выбора разных полей из имен полей

В таблице хранятся данные о валюте, которые обрабатываются два раза в день и в разных валютах, поэтому могут иметь такие поля, как AM_USD, PM_USD, AM_EUR и т. Д. И мне нужно получить данные, такие как список даты против PM_USD или дату против AM_EUR.

Я хотел бы иметь возможность вызывать данные с помощью лямбда-выражения, например (это раздели пример):

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

Я пытался написать функцию, чтобы сделать это, и я неудачно.

Ближайшим мне удалось это:

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

Который терпит неудачу с "System.InvalidOperationException: Lambda параметр не входят в комплект".

Уверен, что я пропустил что-то очевидное или поступил неправильно.

Любые идеи?

Благодаря T

+0

Справедливо ли считать, что вы не можете изменить эту страшную схему для данных? – Lazarus

ответ

4

x.Foo является членом из x (свойство или поле), а не параметр:

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(); 
} 
+0

Привет, Марк, это отличный ответ и возвращает правильное выражение, но теперь я буду казаться глупым ... Как мне назвать этот метод? var data = TableData.Select (CreateSelect ("fieldname")); возвращается с a System.ArgumentNullExpception и спрашивает меня: «Попробуйте указать аргументы типа explicity» Спасибо T –

+0

@Toby - Где это ошибка? –

+0

@Marc - Это не позволит мне скомпилировать код. Эта строка работает нормально: var tst = CreateSelect («AMUSD»); Но если я попробую что-то вроде data.Select (CreateSelect («AMUSD»)); это не позволит мне скомпилировать. –

3

Ваш вопрос:

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

Определение поля имя в запросе LINQ в качестве строки может быть выполнено с помощью 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 Entities, LINQ to SharePoint, LINQ to TerraServer, etc). Instead of using language operators or type-safe lambda extension methods to construct your LINQ queries, the dynamic query library provides you with string based extension methods that you can pass any string expression into.

И, кстати, даже думал, что question не совсем идентичны, answer это почти то же самое.

+0

* an * answer; здесь нет ответа *. –

+0

@Marc Gravell: не уверен, что я просто пропустил грамматическую шутку или что-то в этом роде (английский не был моим родным языком), но я связался с * конкретным ответом, и я не вижу ничего плохого в обращении к этому как ответ (как в ответе, который я связал) ... – Nailuj

+0

Я читал его как «ответ на эту категорию вопросов», где «the» (являясь единственной, определенной статьей) относится к «единственно возможному, здравому, разумному ответьте на эту категорию вопросов ». Это не важно, но лингвистически, возможно, «это» было бы яснее, чем «the». –