30 messaggi dal 30 gennaio 2014
Buonasera.
in un progetto a cui mi sto cimentando avrei bisogno di estrarre nella select la foto più recente associata ad un'anagrafica.
Nella query di SQL inserivo una sottoquery al posto del campo che mi restituiva un risultato ordinandola dalla più recente
Faccio un esempio:
SELECT IDANAGRAFICA, COGNOME, NOME, (SELECT TOP 1 NOMEFILE FROM T_FOTO ORDER BY DATAINSERIMENTO DESC) AS FOTO FROM T_ANAGRAFICA .....

Ho qualche difficoltà con entity framework nel senso che non so come rappresentare questo sistema:

public async Task<List<DiverViewModel>> GetDiversForCardIssueAsync(SelectDiverInputModel input)
        {
            IQueryable<Entities.Anagrafica> baseQuery = dbContext.Anagrafica
                .AsNoTracking()
                .Where(a => a.Cognome.StartsWith(input.Cognome) && a.Nome.StartsWith(input.Nome))
                .Include(a => a.Cities)
                .Include(s => s.Cities.States)
                .Include(p => p.Cities.Province)
                .OrderBy(a => a.Cognome).ThenBy(a => a.Nome);

            List<DiverViewModel> viewModel = await baseQuery
                .Select(a => certificationService.GetDivers(a))
                .ToListAsync();

            return viewModel;
        }


Se utilizzo il certificationService per generare una query verso la tabella delle foto in questo modo:
public DiverViewModel GetDivers(Anagrafica anagrafica)
        {
            return new DiverViewModel()
            {
                IdDiver = anagrafica.AnagraficaId,
                Name = $"{anagrafica.Cognome.ToUpper()} {anagrafica.Nome}",
                DDN = anagrafica.DDN.HasValue ? anagrafica.DDN.ToString()[..10] : string.Empty,
                LDN = $"{anagrafica.Cities.AccentCity} - {anagrafica.Cities.States.StateName ?? ""} - {anagrafica.Cities.Province?.ProvName ?? ""}",
                IdMember = anagrafica.MemberId,
                Foto = userService.GetFotoRecente(anagrafica.AnagraficaId).Result.NomeFile
            };
        }

Lo userService.GetFotoRecente mi dice "MySqlConnection is already in use."

Ovviamente in questo punto del programma (ma poi anche in altre) mi serve reperire non una foto della persona, ma l'ultima inserita.
Mi sapreste indicare come usare Entity Framework in un contesto come il mio?

Grazie per la gentilezza

Valter
193 messaggi dal 12 febbraio 2016
Prova ad aggiungere "AsEnumerable()" per forzare l'esecuzione della query.

 
List<DiverViewModel> viewModel = await baseQuery.AsEnumerable()
                .Select(a => certificationService.GetDivers(a))
                .ToListAsync();
 
.
30 messaggi dal 30 gennaio 2014
Grazie per la risposta @Piero92.
Ho provato, ma mi da direttamente questo errore:
'IEnumerable<DiverViewModel>' non contiene una definizione di 'ToListAsync' e non è stato trovato alcun metodo di estensione accessibile 'ToListAsync' che accetta un primo argomento di tipo 'IEnumerable<DiverViewModel>'. Probabilmente manca una direttiva using o un riferimento all'assembly.

Mi sa che devo ragionare in un altro modo, ma in questo momento non riesco a trovare la via giusta.
Dovrebbe poter esserci un modo per includere una subquery all'interno di una fieldlist di un oggetto IQueryable perchè altrimenti dovrei chiamare n query mentre faccio il mapping del viewModel...
Farò ulteriori ricerche...

Valter
Ciao! Premesso che non uso entityframework e quindi dubito di poter essere di aiuto.. posso chiederti se per favore puoi postare il metodo di userService.getfotorecente e anche come hai registrato nel contenitore di servizi la classe userService?
Grazie mille
843 messaggi dal 08 aprile 2009
Nella Include di Cities per States e Provinces devi utilizzare la ThenInclude non un'altra Include.

Qui trovi tutte le spiegazioni perchè per estrapolare i dati correlati ci sono diversi metodi:
https://docs.microsoft.com/it-it/ef/core/querying/related-data/

Tu stai utilizzando questo metodo:
https://docs.microsoft.com/it-it/ef/core/querying/related-data/eager

e devi guardare in particolare il paragrafo "Inclusione di più livelli"
30 messaggi dal 30 gennaio 2014
@laurar181

Nella Include di Cities per States e Provinces devi utilizzare la ThenInclude non un'altra Include.

Ci provo, anche se nel mio caso i dati risiedono su due tabelle differenti, magari rendo la query più snella.

Tu stai utilizzando questo metodo:
https://docs.microsoft.com/it-it/ef/core/querying/related-data/eager

e devi guardare in particolare il paragrafo "Inclusione di più livelli"

Credo che mi hai acceso la luce...
Nel mio caso si tratta di una inclusione filtrata. Stasera provo a metterlo in atto, se funziona (e ti farò sapere) sai che hai una damigiana di caffè pagati...

Valter
30 messaggi dal 30 gennaio 2014
@Maury07

E' una semplice query che seleziona la foto più recente:
public async Task<FotoViewModel> GetFotoRecente(int userId)
        {
            FotoViewModel foto = await dbContext.FotoUsers
                .AsNoTracking()
                .Where(f => f.AnagraficaId == userId)
                .OrderByDescending(f => f.DataCaricamento)
                .Take(1)
                .Select(foto => FotoViewModel.FromEntity(foto))
                .FirstOrDefaultAsync();

            return foto;
        }

Ma il problema me l'ha risolto @laurar181
A cui va la mia damigiana di caffè
Ho risolto così. Ho modificato la ViewModel in questo modo:
public class DiverViewModel
    {
        public int IdDiver { get; set; }
        public string Name { get; set; }
        public string DDN { get; set; }
        public string LDN { get; set; }
        public string IdMember  { get; set; }
        public ICollection<Entities.FotoUtenti> Foto { get; set; }
    }

Quindi la chiamata al DB:
public async Task<List<DiverViewModel>> GetDiversForCardIssueAsync(SelectDiverInputModel input)
        {
            IQueryable<Entities.Anagrafica> baseQuery = dbContext.Anagrafica
                .AsNoTracking()
                .Where(a => a.Cognome.StartsWith(input.Cognome))
                .Include(a => a.Cities)
                .Include(s => s.Cities.States)
                .Include(p => p.Cities.Province)
                .Include(d => d.Fotos
                    .OrderByDescending(f => f.DataCaricamento)
                    .Take(1))
                .OrderBy(a => a.Cognome).ThenBy(a => a.Nome);

            List<DiverViewModel> viewModel = await baseQuery
                .Select(a => certificationService.GetDivers(a))
                .ToListAsync();

            return viewModel;
        }

E infine il mapping tramite il certificationService:
 public DiverViewModel GetDivers(Anagrafica anagrafica)
        {
            return new DiverViewModel()
            {
                IdDiver = anagrafica.AnagraficaId,
                Name = $"{anagrafica.Cognome.ToUpper()} {anagrafica.Nome}",
                DDN = anagrafica.DDN.HasValue ? anagrafica.DDN.ToString()[..10] : string.Empty,
                LDN = $"{anagrafica.Cities.AccentCity} - {anagrafica.Cities.States.StateName ?? ""} - {anagrafica.Cities.Province?.ProvName ?? ""}",
                IdMember = anagrafica.MemberId,
                Foto = anagrafica.Fotos
            };
        }

Adesso sembrerebbe tutto così semplice, alle volte basta confrontarsi per accendere le lampadine.
Grazie, grazie, grazie

Valter
Grazie a te che hai condiviso! E concordo sul fatto che a volte basta anche solo confrontarsi!! Buona serata
Maurizio

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.