13 messaggi dal 08 marzo 2005
Salve a tutti ,ho 2 tabelle correlate uno a molti
    var lq2 = (from l in cntx.FieldPlcAlarmDecodes
                  join m in cntx.AlarmsTranslates on l.sAliasBit equals m.sAliasBit
             where (l.sAlias=="Alarms01")
                 orderby l.sAlias, l.iAddrBit
                 select m).ToList();


Mi succede che lq2 mi da la collection dei valori corretti della tabella child AlarmsTranslates ma mi manca il record base della tabella FieldPlcAlarmDecodes da cui parte la relazione uno a molti.
In pratica ,in debug,facendo una Watch di lq2 ,ho la proprietà FieldPlcAlarmDecode uguale a null,
Io invece vorrei avere anche il record base dal quale viene generata la collection.
Qualcuno mi spiega come ottenere il record base e la collection in una relazione uno a molti?
11.857 messaggi dal 09 febbraio 2002
Contributi
Ciao,
non devi usare join ma devi crearti una proprietà di navigazione in FieldPlcAlarmDecodes che ti permette di accedere ai suoi AlarmsTranslates. In questo modo riuscirai a caricare sia l'entità principale (quella che tu chiami "record padre") che le sue entità dipendenti (la "collezione figli").
Leggi questo che ti spiega come creare la proprietà di navigazione.
https://www.learnentityframeworkcore.com/relationships

A quel punto, la tua query diventerebbe semplicemente:
var lq2 = (cntx.FieldPlcAlarmDecodes.Include("NomeProprietàDiNavigazione")
           where l.sAlias=="Alarms01"
           orderby l.sAlias, l.iAddrBit
           select m).ToList();


lq2 è una lista delle entità principali Per ogni entità principale potrai accedere alle sue entità correlate andando a leggere la proprietà di navigazione.

ciao,
Moreno

Enjoy learning and just keep making
13 messaggi dal 08 marzo 2005
Risolto
Come dicevi te :
                var lq = (cntx.FieldPlcAlarmDecodes.Include("AlarmsTranslate")
                            .OrderBy(l => l.sAliasBit)
                            .Select(l => l)).ToList();


Purtroppo sono ancora piuttosto acerbo su linq ed entity ,ti ringrazio dell'aiuto e dell'ottimo link per capire come fare le relazioni con entity

Ciao e grazie ancora
13 messaggi dal 08 marzo 2005
Scusa ma sempre inerente a quanto sopra , ho un problema stranissimo ,homesso una observable che popolo così:
obslistAlarms = GetAlarms();


dove getAlarms:
ObservableCollection<FieldPlcAlarmDecode> GetAlarms()
{
  using (EY_Model cntx = new EY_Model())
     {
       var lq = (cntx.FieldPlcAlarmDecodes.Include("AlarmsTranslate")
                            .OrderBy(l => l.sAliasBit)
                            .Select(l => l)).ToList();

       //ObservableCollection<FieldPlcAlarmDecode> l1= new ObservableCollection<FieldPlcAlarmDecode>(lq);
       //var ldec= l1.Select(l => l.FieldsPlc).ToList();

                return new ObservableCollection<FieldPlcAlarmDecode>(lq);

      }
}


andando a fare una query sulla observable:
   var pino = obslistAlarms.Select(l => l.FieldsPlc).Distinct().ToList();


se abilitole le 2 righe commentate:
ObservableCollection<FieldPlcAlarmDecode> l1= new ObservableCollection<FieldPlcAlarmDecode>(lq);
var ldec= l1.Select(l => l.FieldsPlc).ToList();
tutto funziona ,se invece le commento ,la creazione della var pino va in errore perchè obslistAlarms
non ha le collection fieldPlc (obslistAlarms.Select(l => l.FieldsPlc) valorizzate.

Che stranezza è ?La generazione di lq Funziona solo se prima creo una observable qualunque nella GetAlarms.
Sembra che il return dalla funzione GetAlarms perda le collection dell'entità principale
11.857 messaggi dal 09 febbraio 2002
Contributi
Ciao,
se FieldsPlc è anch'essa una proprietà di navigazione verso una collezione di entità, devi indicare ad Entity Framework di "caricarla".
var lq = (cntx.FieldPlcAlarmDecodes.Include("AlarmsTranslate").Include("FieldsPlc")
                            .OrderBy(l => l.sAliasBit)
                            .Select(l => l)).ToList();


Non è una stranezza: Entity Framework estrae i dati dal database solo se tu manifesti l'intenzione di volerli leggere. Usando Include glielo fai presente già nella query LINQ e perciò EF comporrà la query SQL con delle JOIN, in modo che tutti i dati che ti interessano siano recuperati nella maniera più efficiente possibile. Questa tecnica si chiama eager loading, di cui puoi leggere qui:
https://www.entityframeworktutorial.net/eager-loading-in-entity-framework.aspx

Poi c'è un'altra tecnica, cioè questa che però ti sconsiglio di usare in questo caso.

var ldec= l1.Select(l => l.FieldsPlc).ToList();

Questa tecnica si chiama lazy loading, di cui puoi leggere qui.
https://www.entityframeworktutorial.net/lazyloading-in-entity-framework.aspx

In questo caso EF carica i dati delle entità correlate solo quando vai a leggere la proprietà FieldsPlc di ciascuna entità principale. Quindi, per ciascun oggetto FieldPlcAlarmDecodes, EF invierà una query SQL al database il che è abbastanza inefficiente ed è un problema noto come Select n+1.
https://stackoverflow.com/questions/97197/what-is-the-n1-selects-problem-in-orm-object-relational-mapping

ciao,
Moreno
Modificato da BrightSoul il 20 luglio 2019 09:31 -

Enjoy learning and just keep making
13 messaggi dal 08 marzo 2005
Ho capito ,molto chiaro.
Avevo già letto quegli articoli ma la teoria è una cosa poi l'applicazione...

Ti ringrazio infinitamente e complimenti.

Ciao
Raffaele

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.