Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Linq expression

1 réponse
Avatar
Chris81
Bonjour,

j'ai cette requête linq

var cible2 = from valeur in listEnregistrement
group valeur by valeur[0] + _Separateur + valeur[1] into myGroup
let x = myGroup.Key.Split(new string[] { _Separateur },
StringSplitOptions.None)
select new Enregistrement(new List<string>() { x[0], x[1],
myGroup.Sum(enregistrement =>
Convert.ToDouble(enregistrement[2])).ToString() });

je cherche à la transformer en requête dynamique. Pour cela je fais

IQueryable enregistrementQueryable = listEnregistrement.AsQueryable();

ParameterExpression param = Expression.Parameter(typeof(Enregistrement),
"Enregistrement");
MemberExpression tableau = Expression.Property(param, "Tableau");

BinaryExpression region = Expression.ArrayIndex(tableau,
Expression.Constant(0)); // Région
BinaryExpression ville = Expression.ArrayIndex(tableau,
Expression.Constant(1)); // Ville
BinaryExpression ca = Expression.ArrayIndex(tableau,
Expression.Constant(2));//CA

//Je concatene ma cle region et ville

MethodCallExpression cle =
Expression.Call(typeof(String).GetMethod("Concat", new[] { typeof(string),
typeof(string), typeof(string) }), new Expression[] { region,
Expression.Constant(_Separateur), ville });

LambdaExpression lambda = Expression.Lambda(cle, new
ParameterExpression[] { param });

//je groupe avec cette concatenation
MethodCallExpression GroupByRegionVille = Expression.Call(
typeof(Queryable),
"GroupBy",
new Type[] { enregistrementQueryable.ElementType,
typeof(string) },
Expression.Constant(enregistrementQueryable),
lambda);

//j'execute
IQueryable result =
enregistrementQueryable.Provider.CreateQuery(GroupByRegionVille);

ParameterExpression paramGrouping =
Expression.Parameter(typeof(IGrouping<String, Enregistrement>),
"IGrouping<String, Enregistrement>");

MemberExpression key = Expression.Property(paramGrouping,
"Key");

Expression indexof = Expression.Call(key,
typeof(String).GetMethod("IndexOf", new Type[] { typeof(string) }),
Expression.Constant(_Separateur));
Expression subKey = Expression.Call(key,
typeof(String).GetMethod("Substring", new Type[] { typeof(int),
typeof(int) }), Expression.Constant(0), indexof);

LambdaExpression lambda2 = Expression.Lambda(subKey, new
ParameterExpression[] { paramGrouping });


//Je groupe suivant la ville
MethodCallExpression GroupByVille = Expression.Call(
typeof(Queryable),
"GroupBy",
new Type[] { result.ElementType, typeof(string) },
Expression.Constant(result),
lambda2);

IQueryable result2 = result.Provider.CreateQuery(GroupByVille);

Maintenant je souhaite faire la somme de CA par RegionVille c'est à dire
dans le groupe GroupByRegionVille (plus haut).
De plus si vous avez une méthode pour grouper suivant plusieurs champ
dans une méthode call je suis preneur .

Merci


--
Utilisant le client e-mail révolutionnaire d'Opera :
http://www.opera.com/mail/


--
Utilisant le client e-mail révolutionnaire d'Opera :
http://www.opera.com/mail/

1 réponse

Avatar
Jérémy Jeanson
Bonjour Chris81,

Si j'ai bien compris ton souci, tu as une expression Linq dont tu veux
rendre la création (modification) dynamique... changement de where,
group, ou select.

Si c'est bien le cas, ne serrait il pas plus simple de passer par de
expressions lambda correspondant au découpage de ton expression de base...

je n'ai pas lu tout tout code car il me semblait un peu compliqué pour
le but à atteindre, mais si ton objectif est de convertir l'expression
suivante :

var cible2 = from valeur in listEnregistrement
group valeur by valeur[0] + _Separateur + valeur[1] into myGroup
let x = myGroup.Key.Split(new string[] { _Separateur },
StringSplitOptions.None)
select new Enregistrement(new List<string>() { x[0], x[1],
myGroup.Sum(enregistrement =>
Convert.ToDouble(enregistrement[2])).ToString() });

Autant faire un code du style :

var cible2 = listEnregistrement
.GroupBy(expresionGroup)
.Select(expresionGroup);

et d'affecter dynamiquement expresionGroup et le expresionGroup en
fonction de tes besoins avec des expression lamba (Func<>) plutôt que
d'utiliser Call.
--
Jérémy JEANSON
MCP
http://www.jjeanson.fr