Probleme de cast var en int [Résolu]

Signaler
-
Messages postés
14478
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
8 avril 2020
-
Bonjour,
je m'arrache les cheveux depuis un moment avec le probleme suivant. J'essaye de creer un graph avec chart. Je me retrouve avec l'erreur suivante : Les points de données de séries ne prennent pas en charge les valeurs de type System.Data.Entity.Infrastructure.DbQuery`1[<>f__AnonymousType1`1[System.Decimal]]. Seules les valeurs des types suivants peuvent être utilisées : Double, Decimal, Single, int, long, uint, ulong, String, DateTime, short, ushort.

D'apres ce que je comprends je devrais convertir le résultat de ma requete dans un des formats cités ci-dessus. Mais impossible d'y arriver. Voici mon code :

protected void GetChartData2()
{
Series series = Chart2.Series["Series2"];
series.Color = System.Drawing.Color.Blue;

using (Context db = new Context())
{
if (db.InfoLivraison.Count() > 0)
{
DateTime end = Convert.ToDateTime(DateTime.Now.ToString("dd/MM/yyyy"));
DateTime start = end.AddDays(-7);

List<InfoLivraison> listCA = (from infoLivCA in db.InfoLivraison
where infoLivCA.date_command2 >= start && infoLivCA.date_command2 <= end
select infoLivCA).ToList();

DataTable dt2 = ToDataTable<InfoLivraison>(listCA);

DataTable dtjour = dt2.DefaultView.ToTable("Jours7CA", true, "date_command2");
DataTable dtMontant = dt2.DefaultView.ToTable("Montants7CA", true, "montantCommande");

if (dtjour.Rows.Count != 0)
{

for (int i = 0; i < dtjour.Rows.Count; i++)
{
DateTime selectedDate = Convert.ToDateTime(dtjour.Rows[i]["date_command2"]);
string selectedDateStr = Convert.ToString(selectedDate);

for(int j=0;j<dtjour.Rows.Count;j++)
{
var linqSum = db.InfoLivraison.GroupBy(a => selectedDate)
.Select(b => new { total = b.Sum(a => Convert.ToDecimal(a.montantCommande))});

series.Points.AddXY(selectedDate.ToString("dd/MM/yyyy"), linqSum);
}
}
}
}
}
}


Merci pour votre aide

11 réponses

Messages postés
14478
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
8 avril 2020
374
Bonjour

il y a quelques jours j'ai déjà vu cette ligne "stupide", si t'es le même gars, faudrait lire les réponses que l'on prend la peine d'écrire...
DateTime end = Convert.ToDateTime(DateTime.Now.ToString("dd/MM/yyyy")); 

Exporter un string coute du temps et de la Ram, convertir aussi.
Un dateTime sait tout seul, de lui même, quel jour "il" est.
DateTime.Now.Date. Il suffit de lire MSDN pour l'apprendre. Tu y trouveras qu'il sait aussi quelle heure il est...

Ensuite le type var est à utiliser le moins possible, C# est très fortement typé et var est "très" non typé, forcément des fois ça ne lui plait pas au compilateur.

D'autant que là ça ne sert à rien, mais j'y reviendrai.
Tu crées un type anonyme, qui est une classe sans nom, dans laquelle un champ Total reçois la somme issue d'une requête (c'est donc un double, ha non pardon un decimal!), et tu balances la classe complète (même avec un seul champ c'est une classe complète) au chart. Lequel Chart te demande un double, tu voies le truc?
series.Points.AddXY(selectedDate.ToString("dd/MM/yyyy"), linqSum.total);


Mais comme je te l'ai dit, là un var n'a aucune utilité, et ton convert.ToDecimal pas sûr non plus (avec un double tu peux aller jusqu'à 1.7 × 10^308 avec 16 chiffres significatifs...).

double total =  db.InfoLivraison.GroupBy(a => selectedDate).Sum(b => b.montantCommande);//en supposant que montantCommande soit un nombre





Quand j'étais petit, la mer Morte n'était que malade.
George Burns
Messages postés
14478
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
8 avril 2020
374
PS, quand tu utilises la coloration syntaxique, force le langage C#, le rose fuchsia ça tue les yeux.
Merci
Salut Whismeril, merci pour ta réponse. Oui c'est bien moi l'auteur de la ligne stupide ;)

J'ai essayé ta proposition en incluant un convert.ToDecimal car montantCommande est inseree dans la bdd en type varchar.

decimal total = db.InfoLivraison.GroupBy(a => selectedDate).Sum(b => Convert.ToDecimal(b.montantCommande));

je me retrouve avec une erreur :"IGrouping<DateTime, InfoLivraison>' does not contain a definition for 'montantCommande' and no extension method 'montantCommande' accepting a first argument of type 'IGrouping<DateTime, InfoLivraison>' could be found


Je ne comprends pas ce qu'il se passe.
Messages postés
14478
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
8 avril 2020
374
Alors ça peut être
 double total =  db.InfoLivraison.GroupBy(a => selectedDate).Select(b => b.Sum(x => Convert.ToDouble(x.montantCommande)));


Quand j'étais petit, la mer Morte n'était que malade.
George Burns
Cette fois ci j'ai comme erreur : Cannot implicitly convert type 'System.Linq.IQueryable<double>' to 'double'
Messages postés
14478
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
8 avril 2020
374
Il faudrait que tu me donnes la structure de tes données, et le résultat que tu veux.
Parce qu'il n'y a surement pas qu'un seul b.
Donc on a une collection de somme et le chart il veut un nombre.
ok. Voici le class InfoLivraison
public partial class InfoLivraison
    {
        public int ID { get; set; }
        public string Nom { get; set; }
        public string Prenom { get; set; }
        public string Email { get; set; }
        public string Telephone { get; set; }
        public string ModePay { get; set; }
        public string Info { get; set; }
        public string Offre { get; set; }
        public Nullable<int> SessionNB { get; set; }
        public string heure_command { get; set; }
        public string date_command { get; set; }
        public string adresse { get; set; }
        public string CP { get; set; }
        public string ville { get; set; }
        public string montantCommande { get; set; }
        public Nullable<System.DateTime> date_command2 { get; set; }
    }


Je cherche à obtenir le total de montantCommande entre 2 dates afin de pouvoir avoir en x du graphe ttes les dates comprises ainsi que la valeur du total par jour en y
Messages postés
14478
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
8 avril 2020
374
ET dt2 à quoi il sert là dedans?
Messages postés
14478
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
8 avril 2020
374
Et pourquoi elle est partielle ta classe?
Peux tu montrer la suite de la définition?
le datatable dt2 est rempli par la liste listCA. Voici la fonction ToDataTable:
public static DataTable ToDataTable<T>(List<T> items)
{
DataTable dataTable = new DataTable(typeof(T).Name);

//Get all the properties
PropertyInfo[] Props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (PropertyInfo prop in Props)
{
//Setting column names as Property names
dataTable.Columns.Add(prop.Name);
}
foreach (T item in items)
{
var values = new object[Props.Length];
for (int i = 0; i < Props.Length; i++)
{
//inserting property values to datatable rows
values[i] = Props[i].GetValue(item, null);
}
dataTable.Rows.Add(values);
}
//put a breakpoint here and check datatable
return dataTable;
}


La classe InfoLivraison est crée automatiquement par entity framework
Messages postés
14478
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
8 avril 2020
374
Bonsoir

essaye ça
   List<InfoLivraison> maListe = new List<InfoLivraison>
            {
                new InfoLivraison{ date_command2 = new DateTime(2017,10,01), montantCommande = "14"},
                new InfoLivraison{ date_command2 = new DateTime(2017,10,11), montantCommande = "14"},
                new InfoLivraison{ date_command2 = new DateTime(2017,10,11), montantCommande = "22"},
                new InfoLivraison{ date_command2 = new DateTime(2017,10,12), montantCommande = "15"},
                new InfoLivraison{ date_command2 = new DateTime(2017,10,13), montantCommande = "17"},
                new InfoLivraison{ date_command2 = new DateTime(2017,10,18), montantCommande = "32"},
                new InfoLivraison{ date_command2 = new DateTime(2017,10,18), montantCommande = "11"},
                new InfoLivraison{ date_command2 = new DateTime(2017,10,19), montantCommande = "39"},
                new InfoLivraison{ date_command2 = new DateTime(2017,10,19), montantCommande = "24"}
           };

            var requete = (from info in maListe
                           where info.date_command2 >= DateTime.Now.Date.AddDays(-7) && info.date_command2 <= DateTime.Now.Date
                           group info by info.date_command2 into groupe
                           select new
                           {
                               Date = groupe.Key,
                               Total = groupe.Sum(x => Convert.ToDouble(x.montantCommande))
                           }).ToList();

         
           foreach(var couple in requete)
            {
                series.Points.AddXY(couple.Date.ToString(), couple.Total);
            }



ton code fonctionne ! Je comprends pas pourquoi l'autre ne fonctionne pas. J'en perds mes cheveux lol
Messages postés
14478
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
8 avril 2020
374
C'est avec le groupie que ça merdait
>
Messages postés
14478
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
8 avril 2020

Je te remercie pour ton aide. Take care
Messages postés
14478
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
8 avril 2020
374
Maintenant que ça marche, on élimine les var.
Là j'ai choisi d'utiliser un dictionnaire, mais y'a d'autres solutions

           List<InfoLivraison> maListe = new List<InfoLivraison>
            {
                new InfoLivraison{ date_command2 = new DateTime(2017,10,01), montantCommande = "14"},
                new InfoLivraison{ date_command2 = new DateTime(2017,10,11), montantCommande = "14"},
                new InfoLivraison{ date_command2 = new DateTime(2017,10,11), montantCommande = "22"},
                new InfoLivraison{ date_command2 = new DateTime(2017,10,12), montantCommande = "15"},
                new InfoLivraison{ date_command2 = new DateTime(2017,10,13), montantCommande = "17"},
                new InfoLivraison{ date_command2 = new DateTime(2017,10,18), montantCommande = "32"},
                new InfoLivraison{ date_command2 = new DateTime(2017,10,18), montantCommande = "11"},
                new InfoLivraison{ date_command2 = new DateTime(2017,10,19), montantCommande = "39"},
                new InfoLivraison{ date_command2 = new DateTime(2017,10,19), montantCommande = "24"}
           };

            Dictionary<string, double> requete = (from info in maListe
                                                  where info.date_command2 >= DateTime.Now.Date.AddDays(-7) && info.date_command2 <= DateTime.Now.Date
                                                  group info by info.date_command2 into groupe
                                                  select new
                                                  {
                                                      Date = ((DateTime)groupe.Key).ToShortDateString(),
                                                      Total = groupe.Sum(x => Convert.ToDouble(x.montantCommande))
                                                  }).ToDictionary(x => x.Date, x => x.Total);

            foreach(KeyValuePair<string,double> couple in requete)
            {
                series.Points.AddXY(couple.Key, couple.Value);
            }

Messages postés
14478
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
8 avril 2020
374
On peut même faire sans intermédiaire
            List<InfoLivraison> maListe = new List<InfoLivraison>
            {
                new InfoLivraison{ date_command2 = new DateTime(2017,10,01), montantCommande = "14"},
                new InfoLivraison{ date_command2 = new DateTime(2017,10,11), montantCommande = "14"},
                new InfoLivraison{ date_command2 = new DateTime(2017,10,11), montantCommande = "22"},
                new InfoLivraison{ date_command2 = new DateTime(2017,10,12), montantCommande = "15"},
                new InfoLivraison{ date_command2 = new DateTime(2017,10,13), montantCommande = "17"},
                new InfoLivraison{ date_command2 = new DateTime(2017,10,18), montantCommande = "32"},
                new InfoLivraison{ date_command2 = new DateTime(2017,10,18), montantCommande = "11"},
                new InfoLivraison{ date_command2 = new DateTime(2017,10,19), montantCommande = "39"},
                new InfoLivraison{ date_command2 = new DateTime(2017,10,19), montantCommande = "24"}
           };

 
            foreach(IGrouping<DateTime?,InfoLivraison> couple in maListe.Where(info => info.date_command2 >= DateTime.Now.Date.AddDays(-7) && info.date_command2 <= DateTime.Now.Date).GroupBy(info => info.date_command2))
            {
                series.Points.AddXY(((DateTime)couple.Key).ToShortDateString(), couple.Sum(x => Convert.ToDouble(x.montantCommande)));
            }