44 messaggi dal 20 maggio 2003
Ciao a tutti, scusate ma sono 2 giorni che non riesco a capire come lavora EF Core.
Supponiamo di avere 1 entità padre ed N entità figli (1 a molti) ed esplicitare le relazioni sul Dbcontext da entrambe le parti.
Supponiamo di realizzare i rispettivi DTO identici in modo da creare le mappe nel modo più veloce.
Ora se si esegue una semplice query utilizzando il metodo Include si ottiene un JSON infinito.
var query = context.Padre.Include(f => f.Figli).ToList();
Significa che il padre ha dei figli i quali hanno un padre e così via....
Sulla rete si trova la parziale soluzione di inserire la seguente riga nello startup.cs:

options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore

Onestamente mi sembra di nascondere il problema e non risolverlo.
Io sto cercando di capire se è possibile utilizzare l'Include includendo sempre e solo le proprietà del DTO
senza le eventuali relazioni in modo da conrollare sempre quali entità si vogliono estrarre.

Qualcuno è riuscito?
897 messaggi dal 11 febbraio 2013
Non devi configurare da entrambe le parti le relazioi
Poi non capisco perche non proietti nel dto quello che ti serve dopo aver messo include che ti aiuta nell outer join

Magari ho capito male quello che chiedi
44 messaggi dal 20 maggio 2003
Ciao e grazie della risposta.
Le relazioni le ho configurate da entrambe le parti perché le uso entrambe. Sto sviluppando delle API Rest che a volte mi passano il padre e vogliono i figli, a volte vogliono la lista dei figli con il relativo padre.
Se io dovessi proiettare nel dto quello che serve, dovrei fare N dto per la stessa entità.
La soluzione che stavo cercando, ovviamente se possibile, era quella di considerare tutti gli include come include delle sole proprietà senza le rispettive relazioni. Questo metodo lo si usa già facendo le conversioni a mano con delle classi (classico modello: entità, dto, converter).
Usando l'automapper mi chiedevo se era possibile avere questa opzione, sarebbe molto interessante oltre che apprezzata. Ti gitro un link dove forse anche altri stanno avendo le stesse problematiche.
https://stackoverflow.com/questions/54422050/ef-core-reference-loop-when-using-include-and-theninclude
grazie comunque della tua collaborazione.
11.862 messaggi dal 09 febbraio 2002
Contributi
Ciao,


Le relazioni le ho configurate da entrambe le parti perché le uso entrambe.

Ok, sì, tu intendi le "proprietà di navigazione". Va bene che siano da entrambe le parti, se ne hai bisogno.
Quando hai scritto "relazioni", Jonata aveva capito che dal metodo OnModelCreating avevi mappato le relazioni due volte, la prima dal punto di vista dell'entità principale e la seconda dal punto di vista dell'entità dipendente. Ma non era questo il caso, perciò chiamale "proprietà di navigazione" così eviterai fraintendimenti.


Se io dovessi proiettare nel dto quello che serve, dovrei fare N dto per la stessa entità.

È corretto così, non aver paura di creare N dto.

Se devi restituire una lista di padre -> figli, ti crei 3 DTO.
  • ListResultDto è la classe che restituirai e che conterrà una proprietà array che contiene i padri
  • ParentDto è la classe che rappresenta il padre e contiene una proprietà array che contiene i figli
  • ChildDto è la classe che rappresenta il figlio


Ecco un esempio:
public class ListResultDto
{
   public ParentDto[] Results { get; set; } //Elenco dei padri
}

public class ParentDto
{
   public ChildDto[] Children { get; set; }  //Elenco dei figli

   //Qui crei altre proprietà specifiche del padre, ad esempio:
   public string Description { get; set; }
}

public class ChildDto
{
   //Qui le proprietà specifiche del figlio, ad esempio:
   public string Description { get; set; }
}


ciao,
Moreno

Enjoy learning and just keep making
44 messaggi dal 20 maggio 2003
Ciao Moreno e grazie della risposta.
Si le relazioni nell'OnModelCreating sono state mappate da entrambe le parti (uno-a-molti e molti-a-uno), (HasOne e WithMany figlio, e HasMany WithOne nel padre) sbagliato?
La strada degli N dto non mi piace molto perché in questa webapi avrò moltissime tabelle,
e purtroppo se replico per ogni entità n dto ho paura che diventi ingestibile.
Sto valutando altre 2 strade. La prima è di abbandonare l'automapper e di gestire con una classe
la conversione tra i dto passando un parametro che mi determina il grado di conversione.
public EsempioDto DtoFromEntity(Tipologia entity, int conversionType) {
if(conversionType = 0)
// converto solo l'Id
if(conversionType = 1) {
// converto solo le proprietà
}
if(conversionType = 2) {
// converto le proprietà di navigazione
}
}
}

Altra strada è di usare l'automapper, ma di settare a runtime la mappa che mi serve escludendo alcune proprietà di navigazione (specialmente quelle Inverse).
var config = new MapperConfiguration(cfg => {
cfg.CreateMap<PadreEntity, PadreDto>();
cfg.CreateMap<Figlio, FiglioDto>()
.ForMember(m => m.Padre, o => o.Ignore());
});
IMapper iMapper = config.CreateMapper();
ris = iMapper.Map<IEnumerable<FiglioDto>>(RisultatoQuery);

Forse sono ancora all'inizio e ho bisogno di entrare nell'ordine di questi motori di persistenza,
ma non trovo logico che mi escano JSON dove i figli mi replicano il padre...
Mi basterebbe per ora escludere almeno le proprietà di navigazione "contrarie".

Grazie comunque a tutti per la collaborazione
Modificato da jjlotus il 30 settembre 2019 09:56 -
Modificato da jjlotus il 30 settembre 2019 09:57 -
Modificato da jjlotus il 30 settembre 2019 10:06 -
Modificato da jjlotus il 30 settembre 2019 10:07 -

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.