10.967 messaggi dal 09 febbraio 2002
Contributi
Ciao,


Debbo creare tanti Dto per ogni entità ?

No, dipende dalla situazione. Comincia a costruire la prima pagina di dati e poniti questa domanda: "Quali dati devo visualizzare lato client"? Esempio: devo creare una pagina di elenco dei clienti e in questa pagina metterò una tabella con le colonne Ragione sociale, Partita Iva e Data Inserimento. Data questa premessa, crei un dto chiamato ListaClientiDto (o CustomerListDto se preferisci l'inglese) e ci metti dentro le proprietà RagioneSociale, PartitaIva e DataInserimento.

Poi, cliccando il dettaglio si entra nella scheda del cliente. Che dati devo visualizzare? -> creo un dto che contenga quelle proprietà.

A volte un dto contiene proprietà provenienti da svariate entità oppure frutto dell'aggregazione di svariate entità, come in questo caso.


esempio se voglio raggruppare la somma delle fatture per anno.

Crei un dto chiamato RaggruppamentoFatturePerAnnoDto che conterrà le proprietà Anno e Totale. Restituisci al client una lista di questi dto, uno per anno, così che il client non debba fare altro che presentare i dati.


somme e raggruppamenti debba farlo lato client:

I calcoli lato client falli solo se stai sviluppando un motore 3D o un malware per minare i bitcoin.

ciao,
Moreno
Modificato da BrightSoul il 06 giugno 2018 21.01 -

Enjoy learning and just keep making
692 messaggi dal 11 febbraio 2013
Ok
Chiaro

Grazie

Anche se non ho capito il riferimento al malware :)

Ciao Maestro
10.967 messaggi dal 09 febbraio 2002
Contributi
Ahah, spiego meglio: gli utenti vogliono che l'applicazione web sia reattiva. Se fai calcoli lato client, l'interfaccia diventa irresponsiva perché in javascript hai un solo thread che può o calcolare o aggiornare l'interfaccia. (Tralasciando i web workers per il momento).

Se fai i calcoli lato client è perché:
  • Servono ad aggiornare l'interfaccia molte volte al secondo, come nel caso dei giochi;
  • Servono a far funzionare un malware che sfrutta la CPU di utenti inconsapevoli per proprio tornaconto; come nel caso dei miner javascript a cui mi riferivo.


ciao,
Moreno

Enjoy learning and just keep making
692 messaggi dal 11 febbraio 2013
ciao Moreno
ho provato a fare un dto per gli ordini da evadere

public class InevasoDto
    {

        [JsonProperty(propertyName: "dataConsegna")]
        public DateTime? TestateConsegna { get; set; }

        [JsonProperty(propertyName: "documento")]
        public string TestateTipdoc { get; set; }

        [JsonProperty(propertyName: "nrOrdine")]
        public int TestateNumord { get; set; }

        [JsonProperty(propertyName: "quantità")]
        public double? RigheQuanti { get; set; }
        
        [JsonProperty(propertyName: "importo")]
        public double? RigheImport { get; set; }
       
        [JsonProperty(propertyName: "linea")]
        public string linea { get; set; }
       
    }


nella webapi

 [HttpGet]
        public IHttpActionResult GetRIGHE(string id)
        {
            var ordiniInevasi = db.RIGHE
                .Include(c=>c.TESTATE)
                .Where(c=> c.TESTATE.Codcli == id &&...)
                .GroupBy(g=> new
                {
                    g.TESTATE.Numord,
                    g.TESTATE.Tipdoc,
                    g.TESTATE.Datord,
                    ...
                })
                .Select(i=> new InevasoDto
                {
                    Data = i.Key.Datord,
                    Consegna = i.Key.Consegna,
                    ...
                    Import = i.Sum(x=> x.Import),
                    Quanti = i.Sum(x=> x.Quanti)
                })
                .ToList();

            if (!ordiniInevasi.Any())
              return NotFound();
           

            return Ok(ordiniInevasi);
        }


ho fatto il test e la webapi funziona

Ora le tabelle Testate e Righe le ho associate per i campi chiave
come posso usare Automapper in questa situazione?
con una sola entità è semplice

var customersDto = customersQuery
                               .ToList()
                               .Select(Mapper.Map<Customer, CustomerDto>);


ma qui come posso fare ?
grazie ancora

un ultima cosa:
creare un oggetto cliente cosi e riempirlo con le promise di javascript è sbagliato ?

var cliente = {
ordini: [],
inevaso: [],
fatturato:[]
...
};
Modificato da jjchuck il 11 giugno 2018 18.17 -
10.967 messaggi dal 09 febbraio 2002
Contributi
Ciao,
l'extension method Select vuole una lambda che accetta come parametro l'elemento della lista (Customer) e restituisce un elemento di un altro tipo (CustomerDto). Comunque, non ti conviene fare così perché il .ToList() che hai messo prima causerà il caricamento in memoria dell'intera entità (e delle eventuali entità correlate, se hai usato Include). È uno spreco perché a te serve solo un sottoinsieme delle proprietà dell'entità. Allora puoi usare le queryable extension di Automapper come vedi qui, nella documentazione.
http://docs.automapper.org/en/stable/Queryable-Extensions.html

Riporto un paragrafo, ma tu leggi bene tutta la pagina

The .ProjectTo<OrderLineDTO>() will tell AutoMapper&#8217;s mapping engine to emit a select clause to the IQueryable that will inform entity framework that it only needs to query the Name column of the Item table, same as if you manually projected your IQueryable to an OrderLineDTO with a Select clause.


ciao,
Moreno
Modificato da BrightSoul il 12 giugno 2018 20.09 -

Enjoy learning and just keep making
692 messaggi dal 11 febbraio 2013
Ho fatto cosi

 public class MappingProfile: Profile
    {
        public MappingProfile()
        {
           //Domain to Dto
            var config = new MapperConfiguration(cfg => {
                cfg.CreateMap<Fatture, FattureDto>();
                ...
                cfg.CreateMap<Righe, InevasoDto>()
                    .ForMember(dto => dto.Numord, conf => conf.MapFrom(rio => rio.Ordini.Numord));
            });

            IMapper mapper = config.CreateMapper();
           
        }
    }



Global.asax

 protected void Application_Start()
        {
            Mapper.Initialize(c=>c.AddProfile<MappingProfile>());
...
}


InevasoDto

public class InevasoDto
    {
        //Ordini (testate)
        [JsonProperty(propertyName: "dataOrdine")]
        public DateTime? Datord { get; set; }
       
        [JsonProperty(propertyName: "documento")]
        public string Tipdoc { get; set; }

        //Righe (righe ordine)
        [JsonProperty(propertyName: "quantità")]
        public double? Quanti { get; set; }
        
        [JsonProperty(propertyName: "importo")]
        public double? Import { get; set; }
        ...

    }


api inevaso

public IHttpActionResult GetRIORCL(string id)
{
            var ordiniInevasi = db.Righe
                .Where(c => c.Ordini.Codcli == id
                            && c.Statoriga == 0
                            && c.Ordini.Anno == DateTime.Now.Year
                            )
                .GroupBy(g => new
                {
                    g.Ordini.Numord,
                    g.Ordini.Tipdoc,
                    g.Ordini.Datord,
                    g.linea
                })
                .Select(i => new 
                {
                    Datord = i.Key.Datord,
                    Numord = i.Key.Numord,
                    Tipdoc = i.Key.Tipdoc,
                    linea= i.Key.linea,
                    Import = i.Sum(x => x.Import),
                    Quanti = i.Sum(x => x.Quanti)
                })
                .ProjectTo<InevasoDto>()
                .ToList();
                
            if (!ordiniInevasi.Any())
              return NotFound();
           
            return Ok(ordiniInevasi);
        }


Ora seppure ho aggiunto solo un campo nella configurazione ( .ForMember(dto => dto.Numord, conf => conf.MapFrom(rio => rio.Ordini.Numord));) la webapi ritorna tutti i campi previsti in InevasoDto.

Debbo specificare che tra Ordini e Righe non ci sono FK ma un'associazione tra campi chiave che ho fatto
io.

Cosa significa ?

grazie per la pazienza...non ho ben compreso il tutto

ma cerco di seguire ogni tua indicazione come fosse oro

ciao
Modificato da jjchuck il 15 giugno 2018 12.54 -

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.