2010-11-18 11 views
7

Potrzebuję uzyskać dwa pola z tabeli bazy danych (pobranej przy użyciu linq-sql), jedno pole to data-godzina (i jest stałym polem), a drugie jest zawsze dziesiętny, ale pole może być inne.Używanie wyrażenia Lambda do wybrania różnych pól z nazw pól

W tabeli znajdują się dane walutowe, które są przetwarzane dwa razy dziennie w różnych walutach, mogą więc zawierać pola takie jak AM_USD, PM_USD, AM_EUR itd. Muszę też uzyskać dane takie jak lista daty w odniesieniu do PM_USD lub data przeciwko AM_EUR.

Chciałbym móc wywołać dane za pomocą wyrażenia lambda na przykład (to jest okorowane przykład):

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

staram się napisać funkcję, aby to zrobić, i jestem zawiodły.

Najbliższy I udało się:

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

Które nie powiedzie się z "System.InvalidOperationException: Lambda parametr nie w zakres".

Jestem pewien, że pominąłem coś oczywistego lub podążałem w tym kierunku w niewłaściwy sposób.

Wszelkie pomysły?

Dzięki T

+0

Czy można założyć, że nie można zmienić tak strasznego schematu danych? – Lazarus

Odpowiedz

4

x.Foo jest członkiem z x (własność lub pola), a nie parametr:

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

Cześć Marc, to jest świetna odpowiedź i zwraca poprawną epoksję, ale teraz mam zamiar brzmieć głupio ... Jak mogę nazwać tę metodę? var data = TableData.Select (CreateSelect ("nazwa pola")); wraca z a System.ArgumentNullExpception i pyta mnie "Spróbuj sprecyzować argumenty typu explicity" Dzięki T –

+0

@Toby - Gdzie to błąd? –

+0

@Marc - Nie pozwoli mi skompilować kodu. Ta linia działa poprawnie: var tst = CreateSelect ("AMUSD"); Ale jeśli spróbuję czegoś takiego jak dane. Wybierz (CreateSelect ("AMUSD")); nie pozwoli mi się skompilować. –

3

Od zapytanie:

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

Określanie pola nazwa w kwerendzie LINQ jako ciąg może być wykonana za pomocą 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.

A swoją drogą, nawet nie pomyślał question jest dokładnie identyczne, answer jest prawie taka sama.

+0

* an * odpowiedź; nie ma tutaj * odpowiedzi *. –

+0

@Marc Gravell: nie jestem pewien, czy pominąłam żart lub coś gramatycznego (angielski nie jest moim ojczystym językiem), ale łączyłem się z * a * konkretną odpowiedzią i nie widzę niczego złego w powoływaniu się na to jako odpowiedź (jak w odpowiedzi, z którą się łączyłem) ... – Nailuj

+0

Czytam to jako "odpowiedź na tę kategorię pytań", gdzie "the" (jako pojedynczy, określony artykuł) odnosi się do "jedynego możliwego, rozsądnego, rozsądnego odpowiedź na tę kategorię pytań ". To nie jest ważne, ale językowo, być może "to" byłoby wyraźniejsze niż "to". –

Powiązane problemy