using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; namespace test_jointure { class Synthese { private static void MaSynthese(Championnat champ, DataGridView dtw) { var synthese = (from m in champ.manches from p in m.participants group new { Points <bold>p.Points, Nom</bold> p.Nom, Numero = m.Numero } by p.Nom into pGroupes let total <bold>pGroupes.Sum(p</bold>> p.Points) let nombreManches = champ.manches.Count select new { Nom = pGroupes.Key, Total = total, Manche1 <bold>pGroupes.Where(c</bold>> c.Numero == 1).DefaultIfEmpty(new { Points = 0, Nom = "", Numero = 0 }).ElementAt(0).Points, Manche2 <bold>pGroupes.Where(c</bold>> c.Numero == 2).DefaultIfEmpty(new { Points = 0, Nom = "", Numero = 0 }).ElementAt(0).Points, Manche3 <bold>pGroupes.Where(c</bold>> c.Numero == 3).DefaultIfEmpty(new { Points = 0, Nom = "", Numero = 0 }).ElementAt(0).Points, //en ajoutant ici autant de MancheN que nécessaire } ).ToList(); dtw.DataSource = synthese; } } }
//ecriture du code dans un stringbuilder StringBuilder codeDynamique = new StringBuilder(); //partie du code "fixe" codeDynamique.AppendLine("using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms;"); codeDynamique.AppendLine("namespace test_jointure {"); codeDynamique.AppendLine("public class Synthese {"); codeDynamique.AppendLine("public static void Calcul(Championnat champ, DataGridView dtw)"); codeDynamique.AppendLine("{"); codeDynamique.AppendLine("var synthese = (from m in champ.manches"); codeDynamique.AppendLine("from p in m.participants"); codeDynamique.AppendLine("group new { Points <bold>p.Points, Nom</bold> p.Nom, Numero = m.Numero } by p.Nom into pGroupes"); codeDynamique.AppendLine("let total <bold>pGroupes.Sum(p</bold>> p.Points)"); codeDynamique.AppendLine("let nombreManches = champ.manches.Count"); codeDynamique.AppendLine("select new"); codeDynamique.AppendLine("{"); codeDynamique.AppendLine("Nom = pGroupes.Key,"); codeDynamique.AppendLine("Total =total,"); //partie du code modulable, je décris un champ manche autant de fois que nécessaire string texteAvecAccolades <bold>"new { Points</bold> 0, Nom = string.Empty, Numero = 0 }";//pour le string.Format je trouve plus lisble de faire ainsi que d'échapper l'accolade par \\\\... for (int i = 0;i<champ.manches.Count;i++) codeDynamique.AppendLine(string.Format("Manche{0} <bold>pGroupes.Where(c</bold>> c.Numero == {0}).DefaultIfEmpty({1}).ElementAt(0).Points,", i + 1, texteAvecAccolades)); //fin fixe codeDynamique.AppendLine("}).ToList();"); codeDynamique.AppendLine("dtw.DataSource = synthese;"); codeDynamique.AppendLine("}"); codeDynamique.AppendLine("}}"); string code = codeDynamique.ToString(); //compilation dynamique CSharpCodeProvider provider = new CSharpCodeProvider(); ICodeCompiler compileur = provider.CreateCompiler(); CompilerParameters cp = new CompilerParameters(); //Ajout des références nécessaire, j'ai pris toutes les références du projet et supprimé une par ou pour voir celles qui étaient vraiment necessaires cp.ReferencedAssemblies.Add(@"System.dll"); cp.ReferencedAssemblies.Add(@"System.Core.dll"); cp.ReferencedAssemblies.Add(@"System.Windows.Forms.dll"); cp.ReferencedAssemblies.Add(@"test jointure.exe");//le projet en cours, car j'utilise le type Cahmpionnat //compilation CompilerResults cr = provider.CompileAssemblyFromSource(cp,code); if (cr.Errors.Count == 0)//appel de la méthode Calcul de la classe Synthese cr.CompiledAssembly.GetType("test_jointure.Synthese").GetMethod("Calcul").Invoke(null, new object[] { champ, dataGridView1 });
public class ResultatGroupe { public string Pseudo { get; set; } public int TotalPoints { get; set; } public List<ResulatUnitaire> Resultats { get; set; } public int GetPoints(int numero)//Dynamic.cs ne peut pas accéder à cette méthode. { if (Resultats.Exists(x => x.Numero == numero)) return Resultats.First(x => x.Numero == numero).Points; else return 0;//il y a sans doute mieux à faire avec un DefaultIfEmpty, mais je n'ai pas cherché à optimiser cette partie } #region Résultats détaillés //listing des résultats public int R1 { get { if (Resultats.Exists(x => x.Numero == 1)) return Resultats.First(x => x.Numero == 1).Points; else return 0; } } public int R2 { get { if (Resultats.Exists(x => x.Numero == 2)) return Resultats.First(x => x.Numero == 2).Points; else return 0; } } public int R3 { get { if (Resultats.Exists(x => x.Numero == 3)) return Resultats.First(x => x.Numero == 3).Points; else return 0; } } public int R4 { get { if (Resultats.Exists(x => x.Numero == 4)) return Resultats.First(x => x.Numero == 4).Points; else return 0; } } public int R5 { get { if (Resultats.Exists(x => x.Numero == 5)) return Resultats.First(x => x.Numero == 5).Points; else return 0; } } public int R6 { get { if (Resultats.Exists(x => x.Numero == 6)) return Resultats.First(x => x.Numero == 6).Points; else return 0; } } public int R7 { get { if (Resultats.Exists(x => x.Numero == 7)) return Resultats.First(x => x.Numero == 7).Points; else return 0; } } public int R8 { get { if (Resultats.Exists(x => x.Numero == 8)) return Resultats.First(x => x.Numero == 8).Points; else return 0; } } public int R9 { get { if (Resultats.Exists(x => x.Numero == 9)) return Resultats.First(x => x.Numero == 9).Points; else return 0; } } public int R10 { get { if (Resultats.Exists(x => x.Numero == 10)) return Resultats.First(x => x.Numero == 10).Points; else return 0; } } public int R11 { get { if (Resultats.Exists(x => x.Numero == 11)) return Resultats.First(x => x.Numero == 11).Points; else return 0; } } public int R12 { get { if (Resultats.Exists(x => x.Numero == 12)) return Resultats.First(x => x.Numero == 12).Points; else return 0; } } public int R13 { get { if (Resultats.Exists(x => x.Numero == 13)) return Resultats.First(x => x.Numero == 13).Points; else return 0; } } public int R14 { get { if (Resultats.Exists(x => x.Numero == 14)) return Resultats.First(x => x.Numero == 14).Points; else return 0; } } public int R15 { get { if (Resultats.Exists(x => x.Numero == 15)) return Resultats.First(x => x.Numero == 15).Points; else return 0; } } public int R16 { get { if (Resultats.Exists(x => x.Numero == 16)) return Resultats.First(x => x.Numero == 16).Points; else return 0; } } public int R17 { get { if (Resultats.Exists(x => x.Numero == 17)) return Resultats.First(x => x.Numero == 17).Points; else return 0; } } public int R18 { get { if (Resultats.Exists(x => x.Numero == 18)) return Resultats.First(x => x.Numero == 18).Points; else return 0; } } public int R19 { get { if (Resultats.Exists(x => x.Numero == 19)) return Resultats.First(x => x.Numero == 19).Points; else return 0; } } public int R20 { get { if (Resultats.Exists(x => x.Numero == 20)) return Resultats.First(x => x.Numero == 20).Points; else return 0; } } #endregion } public class ResulatUnitaire { public int Numero { get; set; } public int Points { get; set; } }
List<ResultatGroupe> pGroupes = (from m in Champ.Manches from p in m.Participants group new { Points <bold>p.Points, Numero</bold> m.Numero } by p.Pseudo into groupe select new ResultatGroupe { Pseudo = groupe.Key, TotalPoints = groupe.Sum(x=> x.Points), Resultats <bold>groupe.Select(x</bold>> new ResulatUnitaire{Numero =x.Numero, Points=x.Points}).ToList<ResulatUnitaire>() } ).ToList <ResultatGroupe>(); //partie commune StringBuilder str = new StringBuilder(); str.Append("new ("); str.Append("Pseudo as Pseudo, TotalPoints as Total"); //Partie dynamique for (int i = 0; i < Champ.Manches.Count; i++) { string ligne = string.Format(", R{0} as Manche{0}", i+1);//ici je viens chercher la propriété qui va bien str.Append(ligne); } str.Append(")"); var synthese = pGroupes.AsQueryable().Select(str.ToString());//le Select doit être appliqué à un Iqueriable datagridview1.DataSource = synthese.Cast<object>().ToList();//synthese est donc un Iqueriable qui n'est pas un résulat mais une requête, il n'a pas de méthode ToList pour forcer l'énumération d'ou le cast en object.
var pGroupes = (from m in Champ.Manches from p in m.Participants group new { Points <bold>p.Points, Nom</bold> p.Pseudo, Numero = m.Numero } by p.Pseudo ); var synthese <bold>pGroupes.Select(groupe</bold>> new { Nom = groupe.Key, Total <bold>groupe.Sum(p</bold>> p.Points), groupe.Any(c => c.Numero == 1) ? Manche1 = groupe.First(c => c.Numero == 1).Points : null,//deux erreurs : Erreur 2 Déclarateur de membre de type anonyme non valide. Les membres de type anonyme doivent être déclarés avec une assignation de membre, un nom simple ou un accès membre. Erreur 1 Le nom 'Manche1' n'existe pas dans le contexte actuel Manche2 <bold>groupe.Where(c</bold>> c.Numero == 2).DefaultIfEmpty(new { Points = 0, Nom = "", Numero = 0 }).ElementAt(0).Points,//ça c'est ok Manche3 <bold>groupe.Where(c</bold>> c.Numero == 3).DefaultIfEmpty(new { Points = 0, Nom = "", Numero = 0 }).ElementAt(0).Points,//ça aussi } ).ToList();
var pGroupes = (from m in Champ.Manches from p in m.Participants group new { Points <bold>p.Points, Nom</bold> p.Pseudo, Numero = m.Numero } by p.Pseudo );//je laisse cette requette car je n'arrive pas à "linéariser" les from imbriqués, ça marche ce n'est pas génant var synthese <bold>pGroupes.AsQueryable().Select(g</bold>> new { Nom = g.Key, Total <bold>g.Sum(p</bold>> p.Points), Manche0 <bold>g.Where(c</bold>> c.Numero == 0).DefaultIfEmpty(new { Points = 0, Nom = string.Empty, Numero = 0 }).ElementAt(0).Points, Manche1 <bold>g.Where(c</bold>> c.Numero == 1).DefaultIfEmpty(new { Points = 0, Nom = string.Empty, Numero = 0 }).ElementAt(0).Points, Manche2 <bold>g.Where(c</bold>> c.Numero == 2).DefaultIfEmpty(new { Points = 0, Nom = string.Empty, Numero = 0 }).ElementAt(0).Points, Manche3 <bold>g.Where(c</bold>> c.Numero == 3).DefaultIfEmpty(new { Points = 0, Nom = string.Empty, Numero = 0 }).ElementAt(0).Points, Manche4 <bold>g.Where(c</bold>> c.Numero == 4).DefaultIfEmpty(new { Points = 0, Nom = string.Empty, Numero = 0 }).ElementAt(0).Points, });//cette requête "en dur" dans le code fonctionne, c'est elle que je souhaite rendre dynamique en mettant le nombre de manche qui va bien
//partie commune StringBuilder str = new StringBuilder(); str.Append("new ("); str.Append("Key as Nom, Sum(Points) as Total"); str.Append(")"); var synthese = pGroupes.AsQueryable().Select(str.ToString());
str.Append("Key as Nom, Sum(Points) as Total, ElementAt(0).Points as Manche1");
throw ParseError(errorPos, Res.NoApplicableAggregate, methodName), //avec methodName = ElementAt
str.Append("Key as Nom, Sum(Points) as Total, Where(m=> m.Numero = 1).Points as Manche1");
throw ParseError(errorPos, Res.UnknownPropertyOrField, id, GetTypeName(type))// avec id = m