Probleme de cast var en int [Résolu]

vitruve - 18 oct. 2017 à 18:01 - Dernière réponse : Whismeril 10854 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 22 janvier 2018 Dernière intervention
- 19 oct. 2017 à 19:52
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
Afficher la suite 

16 réponses

Répondre au sujet
Whismeril 10854 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 22 janvier 2018 Dernière intervention - Modifié par Whismeril le 18/10/2017 à 18:38
0
Utile
1
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
Whismeril 10854 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 22 janvier 2018 Dernière intervention - 18 oct. 2017 à 18:39
PS, quand tu utilises la coloration syntaxique, force le langage C#, le rose fuchsia ça tue les yeux.
Merci
Commenter la réponse de Whismeril
0
Utile
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.
Commenter la réponse de vitruve
Whismeril 10854 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 22 janvier 2018 Dernière intervention - Modifié par Whismeril le 18/10/2017 à 19:29
0
Utile
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
Commenter la réponse de Whismeril
0
Utile
Cette fois ci j'ai comme erreur : Cannot implicitly convert type 'System.Linq.IQueryable<double>' to 'double'
Commenter la réponse de vitruve
Whismeril 10854 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 22 janvier 2018 Dernière intervention - 18 oct. 2017 à 20:17
0
Utile
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.
Commenter la réponse de Whismeril
0
Utile
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
Commenter la réponse de vitruve
Whismeril 10854 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 22 janvier 2018 Dernière intervention - 18 oct. 2017 à 21:29
0
Utile
1
ET dt2 à quoi il sert là dedans?
Whismeril 10854 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 22 janvier 2018 Dernière intervention - 18 oct. 2017 à 21:41
Et pourquoi elle est partielle ta classe?
Peux tu montrer la suite de la définition?
Commenter la réponse de Whismeril
0
Utile
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
Commenter la réponse de vitruve
Whismeril 10854 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 22 janvier 2018 Dernière intervention - 18 oct. 2017 à 22:04
0
Utile
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);
            }



Commenter la réponse de Whismeril
0
Utile
2
ton code fonctionne ! Je comprends pas pourquoi l'autre ne fonctionne pas. J'en perds mes cheveux lol
Whismeril 10854 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 22 janvier 2018 Dernière intervention - 18 oct. 2017 à 23:36
C'est avec le groupie que ça merdait
vitruve > Whismeril 10854 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 22 janvier 2018 Dernière intervention - 19 oct. 2017 à 12:14
Je te remercie pour ton aide. Take care
Commenter la réponse de vitruve
Whismeril 10854 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 22 janvier 2018 Dernière intervention - 19 oct. 2017 à 18:12
0
Utile
1
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);
            }

Whismeril 10854 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 22 janvier 2018 Dernière intervention - 19 oct. 2017 à 19:52
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)));
            }
Commenter la réponse de Whismeril

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.