2010-11-18 4 views
7

Je dois obtenir deux champs d'une table de base de données (récupérée en utilisant linq-to-sql), un champ est un datetime (et est un champ fixe) et l'autre est toujours une décimale, mais le champ peut être différent.Utilisation de l'expression Lambda pour sélectionner différents champs des noms de champs

La table contient des données de devise qui sont traitées deux fois par jour et dans des devises différentes, telles que AM_USD, PM_USD, AM_EUR, etc. Et j'ai besoin de données telles qu'une liste de PM_USD ou la date contre AM_EUR.

Je voudrais être en mesure d'appeler les données en utilisant une expression lambda par exemple (ce qui est un dépouillé exemple):

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

Je suis en train d'écrire une fonction pour ce faire, et je suis échouer lamentablement.

Le plus proche que je suis parvenu est:

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

qui échoue avec "System.InvalidOperationException: Lambda Paramètre non portée". Je suis sûr que j'ai manqué quelque chose d'évident, ou que je me suis trompé.

Des idées?

Merci T

+0

Est-il juste de supposer que vous ne pouvez pas modifier ce schéma terrible pour les données? – Lazarus

Répondre

4

x.Foo est un membre de x (propriété ou un champ), pas un paramètre:

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

Salut Marc, c'est une bonne réponse et je retourne l'épxression correcte, mais maintenant je vais paraître stupide ... Comment appeler cette méthode? var data = TableData.Select (CreateSelect ("fieldname")); revient avec une System.ArgumentNullExpception et me demande de "Essayer de spécifier les arguments de type explicites" Merci T –

+0

@Toby - Où est-ce qu'il erreur? –

+0

@Marc - Il ne me laissera pas compiler le code. Cette ligne fonctionne bien: var tst = CreateSelect ("AMUSD"); Mais si j'essaie quelque chose comme data.Select (CreateSelect ("AMUSD")); ça ne me laissera pas compiler. –

3

De votre question:

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

Spécification du champ nom dans une requête LINQ comme une chaîne peut être effectuée en utilisant 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.

Et par ailleurs, même pensé que le question est pas exactement identique, le answer est à peu près la même chose.

+0

* une * réponse; il n'y a pas de * la * réponse ici. –

+0

@Marc Gravell: je ne sais pas si j'ai manqué une blague gramatical ou quelque chose (l'anglais n'étant pas ma langue maternelle), mais je suis lié à * une * réponse spécifique, et je ne vois rien de mal à faire référence à la réponse (comme dans la réponse à laquelle je suis lié) ... – Nailuj

+0

Je l'ai lu comme "la réponse à cette catégorie de question", où "le" (étant l'article singulier, défini) se réfère à "la seule possible, saine, raisonnable répondre à cette catégorie de question ". Ce n'est pas important, mais linguistiquement, peut-être que "ceci" aurait été plus clair que "le". –

Questions connexes