Go Down

Topic: Linq su c# (Read 1 time) previous topic - next topic

82_marco

Ciao a tutti,
Sono nuovo del forum, sto facendo il mio primo programma che utilizza il LINQ, il mio problema e' questo: devo ricavare il primo valore minore a quello di riferimento tra quelli contenuti in una lista.
Ho cominciato a scriver il codice, ma m sono bloccato a causa di 2 errori che non riesco a risolvere.

il mio codice e' questo:



codice:
        private void button1_Click(object sender, EventArgs e)
        {
            XDocument xmlDoc = XDocument.Load(@"c:\a\casse.xml");

            var casse = (from serbatoio in xmlDoc.Descendants("serbatoio")
                         where serbatoio.Attribute("id").Value == ("serbatoio" + NumSerbatoio.Text)
                         select serbatoio).FirstOrDefault().Descendants("valore")
                        .Select(v => new { Altezza = int.Parse(v.Attribute("Altezza").Value), Litri = int.Parse(v.Attribute("litri").Value) }).ToList();

            var prova = (from altezze in casse
                         orderby altezze.Altezza descending
                         select altezze).ToList();

            int altezza1 = prova.FirstOrDefault<int>(x => x > int.Parse(Altezza.Text));

              //       textBox1.Text = casse.ToString();
        } visual studio mi restituisce questi errori nell ultima riga:

Errore 1 'System.Collections.Generic.List<AnonymousType#1>' non contiene una definizione per 'FirstOrDefault' e l'overload migliore del metodo di estensione 'System.Linq.ParallelEnumerable.FirstOrDefault<TSo urce>(System.Linq.ParallelQuery<TSource>, System.Func<TSource,bool>)' presenta alcuni argomenti non validi

Errore 2 Argomento dell'istanza: impossibile convertire da 'System.Collections.Generic.List<AnonymousType#1>' a 'System.Linq.ParallelQuery<int>'

potere aiutarmi a risolvere il mio problema per favore?

grazie

flz47655

Il compilatore ha ragione, x nell'ultima riga è una classe anonima con le proprietà Altezza e Litri, devi esplicitare quale proprietà vuoi confrontare, ad ogni modo crea una classe "normale" e usa quella che rendi più leggibile il codice

Ciao

82_marco

Ciao in che modo posso esplicitare i valori di altezza?

Cosa intendi per classe "normale"?

flz47655

Semplicemente una classe

Ciao

82_marco

intendi senza usare il linq?
puoi spiegarmi come sistemare quegli errori?

flz47655

Come primo indizio la classe che puoi creare può essere:
Code: [Select]

    public class Serbatoio
    {
      public int Altezza { get; set; }
      public int Litri { get; set; }
    }


La classe è da utilizzare con LINQ, non devi stravolgere nulla, ma sai cos'è una classe? Lo davo per scontato visto che utilizzi LINQ

Ciao

flz47655

Secondo suggerimento:
La prima query può diventare con la classe appena creata:

Code: [Select]

List<Serbatoio> casse = (from serbatoio in xmlDoc.Descendants("serbatoio")
                   where serbatoio.Attribute("id").Value == ("serbatoio" + "NumSerbatoio.Text")
                   select serbatoio).FirstOrDefault().Descendants("valore")
                   .Select(x => new Serbatoio()
                   {
                     Altezza = int.Parse(x.Attribute("Altezza").Value),
                     Litri = int.Parse(x.Attribute("litri").Value)
                   }).ToList();

flz47655

Per ricavare l'altezza più grande sotto alla soglia ti conviene utilizzare ancora LINQ per una maggiore leggibilità:

Code: [Select]

int altezza1 = (from p in casse
                      where p.Altezza < int.Parse(Altezza.Text)
                      orderby p.Altezza descending
                     select p.Altezza).FirstOrDefault();


la query associata alla variabile "prova" del codice che avevi postato a questo punto non ti serve e la puoi cancellare
Trovo il codice più pulito con una classe non anonima

Ciao
PS: Nel codice di prima togli da "NumSerbatoio.Text" le virgolette naturalmente

82_marco

Ciao, grazie del consiglio :-) appena torno a casa lo provo... si so cosa e' una classe, ma non riuscivo a capire cosa volevi dirmi  :*
Ti aggiorno sui miei progressi...a dopo

82_marco

Funziona perfettamente :-) grazie di tutto

Go Up