33 messaggi dal 17 maggio 2011
Ciao a tutti,

Ho questo model Plant che al suo interno ha una List<Instrument>
Il model Instrument carica a sua volta una List<ParameterInstruments>.
Il model ParameterInstruments a sua volta è collegato al model <Parameter>
Per recuperare la proprietà value contenuta in ParameterInstruments, confrontando la proprietà name contenuta nel model <Parameter> in una singola istruzione non riesco proprio a capire come fare.
Con un doppio for each nessun problema

            var plant = db.Plants.Find(IdPlant);
            foreach (var ist in plant.Instruments)
            {
                foreach(var param in ist.ParameterInstruments)
                {
                    if(param.Parameter.Name == "MaxDigitals")
                    {
                        ViewBag.MaxDigitals = param.Value;
                    }

                }
            }


Grazie a tutti dell'aiuto
11.511 messaggi dal 09 febbraio 2002
Contributi
Ciao,
dal tuo codice mi sembra di capire che tu sia interessato ad ottenere il valore del primo parametro chiamato "MaxDigitals", anche se ce ne fosse più d'uno. Se è questo il caso, prova a fare così:
ViewBag.MaxDigitals = db.Plants.Where(p => p.Id == plant.Id) //Seleziono la plant che porta l'id che mi interessa
     .SelectMany(p => p.Instruments) //Di tutti gli Intruments di questa Plant
     .SelectMany(i => i.ParameterInstruments) //vado a selezionare tutti i ParameterInstruments
     .Select(pi => pi.Parameter) //sono interessato ai loro Parameter in particolare
     .Where(p => p.Name == "MaxDigitals") //voglio ottenere il Parameter che ha Name=="MaxDigitals"
     .FirstOrDefault()? //ma solo il primo (se c'è)
     .Value; //e restituisco il suo valore, se è stato trovato


Dato che questa query LINQ scatenerà una query al database, ti consiglio di usare la variante asincrona, così farai un utilizzo migliore dei thread di ASP.NET .
ViewBag.MaxDigitals = (await db.Plants.Where(p => p.Id == plant.Id)
     .SelectMany(p => p.Instruments)
     .SelectMany(i => i.ParameterInstruments)
     .Select(pi => pi.Parameter)
     .Where(p => p.Name == "MaxDigitals")
     .FirstOrDefaultAsync())?
     .Value;



Con un doppio for each nessun problema

Ok ma attenzione perché in questo modo, se hai il lazy loading attivo, stai scatenando un casino di query al database in cui recuperi tutti i dati degli Instrument e dei ParameterInstrument, quando invece tu sei interessato ad ottenere uno specifico valore. È un problema chiamato Select n+1.
https://www.brentozar.com/archive/2018/07/common-entity-framework-problems-n-1/

Tieni sempre d'occhio le query SQL che vengono inviate al database usando la funzionalità di logging di Entity Framework.
http://www.entityframeworktutorial.net/entityframework6/database-command-logging.aspx

Verifica qual è la query che viene inviata con il mio esempio (dovrebbe esserne inviata solo una, più complessa) e verifica qual è il suo piano di esecuzione, se usi Sql Server. In questo modo riuscirai a capire quante risorse ti richiede ottenere quel valore.

ciao,
Moreno
Modificato da BrightSoul il 11 marzo 2019 19:38 -

Enjoy learning and just keep making
33 messaggi dal 17 maggio 2011
Bene, non solo mi hai risposto egregiamente alla mia domanda.
Ma hai anche chiarito dubbi di fondo che avevo.
Sei una garanzia, grazie mille.
11.511 messaggi dal 09 febbraio 2002
Contributi
Prego!

Enjoy learning and just keep making

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.