Sto codificando un REST Api in .NET Core con NancyFX in questo momento che recupera i dati da un database usando Entity Framework. Le tabelle all'interno del database hanno vari campi uguali a quelli all'interno delle mie classi modello. Tuttavia non voglio esporre tutti i campi tramite l'API.
per esempio:
Tabella DB Persone:
Scarpe da tavola DB:
L'endpoint /persons
mio REST devono inviare solo ID, nome, sesso senza età insieme a un elenco di scarpe (solo modello):
{id: 1, nome: "Max", sex: "m", "shoes": [{"id": 1, "model": "AirMax"}]}
All'inizio ho pensato che il modo migliore sarebbe stato quello di specificare i campi che voglio mostrare specificandoli all'interno di Select()
. Ma quando ho unito le tabelle, non posso impostare un Select()
su quelle unite. Quindi sto iterando sugli elenchi di entità adesso e creo un nuovo elenco che contiene le proprietà ricercate:
List<object> newPersonList = new List<object>();
foreach(Person p in db.Persons) {
List<object> newShoesList = new List<object>();
foreach(Shoe s in p.Shoes) {
newShoeList.Add(new {...});
}
}
newPersonList.Add(new {...});
}
Ma non sono sicuro che questa forma di post-elaborazione sia quella giusta. Questo potrebbe diventare difficile se ho più tabelle sub-correlate. Tuttavia non voglio esporre tutte le proprietà del modello tramite REST. C'è un'alternativa?
Un paio di cose da considerare:
1) Si desidera solo selezionare dal database i campi che è necessario restituire. Altrimenti, stai sovraccaricando il tuo database più del necessario.
2) Non vuoi restituire le tue entità EF direttamente dalla tua API. Questo accoppierà strettamente il tuo accesso ai dati e il tuo cliente insieme, cosa che vorrai evitare. È necessario utilizzare la proiezione per selezionare solo il campo desiderato e restituirli tramite DTO personalizzati. Il metodo di selezione LINQ e uno strumento di mappatura come AutoMapper (AM) funzionano proprio per questo. Personalmente, preferisco la proiezione di AM rispetto a quella di LINQ, in quanto la mappatura viene eseguita indipendentemente dalla query che consente il riutilizzo quando possibile. Semplifica anche le query nel codice (anche se aggiunge complessità per configurare AM e le sue mappature).
Ho avuto una domanda / risposta circa un anno fa che trattava del raggruppamento, quindi non è esattamente la stessa del tuo esempio, ma mostra tutto il codice necessario per gestire il tuo scenario usando AM. Spero che ti aiuti. LINQ GroupBy Aggregation con AutoMapper
Inoltre, ecco il link alla documentazione di proiezione di AM: http://docs.automapper.org/en/stable/Projection.html