Ho appena iniziato a giocare con il modello WebAPI in ASP.NET Core VS2017 utilizzando Entity Framework Core e sto cercando di capire il modo migliore per restituire un sottoinsieme delle proprietà di un oggetto per una particolare richiesta Get.
Ho usato il built-in scaffolding per generare inizialmente un controller e il metodo di richiesta Get
generato inizialmente era simile a questo:
[HttpGet]
public IEnumerable<Person> GetPeople()
{
return _context.People;
}
Il mio problema era che Person
ha una classe figlia che non voglio includere quando qualcuno fa una chiamata a GetPeople()
.
Dal momento che non voglio restituire un oggetto anonimo, ho invece aggiunto una classe ridotta nel controller chiamato PersonInfo
che ha solo le proprietà che voglio essere restituito, come questo:
public class PersonInfo
{
public int id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string AD { get; set; }
}
e quindi ho aggiornato il metodo GetPeople()
con questo:
[HttpGet]
public IEnumerable<PersonInfo> GetPeople()
{
List<PersonInfo> pi = new List<PersonInfo>();
foreach(var person in _context.People
.Select(p => new { p.id, p.FirstName, p.LastName, p.AD})
.ToList())
{
PersonInfo newPerson = new PersonInfo();
newPerson.id = person.id;
newPerson.FirstName = person.FirstName;
newPerson.LastName = person.LastName;
newPerson.AD = person.AD;
pi.Add(newPerson);
}
return pi;
}
Funziona bene, sembra orribilmente inefficiente. Deve esserci un modo migliore, giusto?
Questo è davvero orribilmente inefficiente. Il metodo dovrebbe assomigliare a questo:
[HttpGet]
public async Task<IEnumerable<PersonInfo>> GetPeople()
{
return await _context.People
// select the data you want directly
.Select(p => new PersonInfo
{
id = p.id,
FirstName = p.FirstName,
LastName = p.LastName,
AD = p.AD
})
// always use the asynchronous version of EF Core extension methods
.ToListAsync();
}
A proposito, dovresti IActionResult
a utilizzare l'interfaccia IActionResult
in ASP.NET Core. Ciò consente di personalizzare facilmente il codice di stato e il modo in cui i dati vengono restituiti. È molto più preferibile usare qualcosa come:
[HttpGet]
public async Task<IActionResult> GetPeople()
{
var data = await _context.People
// select the data you want directly
.Select(p => new PersonInfo
{
id = p.id,
FirstName = p.FirstName,
LastName = p.LastName,
AD = p.AD
})
// always use the asynchronous version of EF Core extension methods
.ToListAsync();
return Json(data);
}