ViewModel and Model-ViewModel mapping
A ViewModel selects fields from one or more models to expose a shape adapted to screens, APIs, or grids. ViewModels are generally placed in the Shared project and prefixed with Vm.
Creating a ViewModel
Create a dedicated class containing only the fields to expose to the screen, the API, or the grid. The ViewModel can group properties coming from one or more EF Core models.
Mapping
The Lagoon server framework does not expose a generic Model ↔ ViewModel mapping API. Conversions are application code: create extension methods or project EF Core entities directly in your queries.
The following example shows a simple application-level mapping.
public static class VmPizzaMapping
{
public static VmPizza GetNewVmPizza(this Order order)
{
// Crée un ViewModel à partir du modèle EF Core.
VmPizza vmPizza = new();
vmPizza.MapFromModel(order);
return vmPizza;
}
public static Order GetNewOrder(this VmPizza vmPizza)
{
// Crée un modèle EF Core à partir du ViewModel.
Order order = new();
vmPizza.MapToModel(order);
return order;
}
public static void MapFromModel(this VmPizza vmPizza, Order order = null)
{
// Copie ici les propriétés du modèle vers le ViewModel.
}
public static void MapToModel(this VmPizza vmPizza, Order order = null)
{
// Copie ici les propriétés du ViewModel vers le modèle.
}
}
Example of a shared ViewModel
Lagoon ViewModels follow the general DTO conventions: name prefixed with Vm, public properties, and XML documentation for public members.
public class VmCountryFirm
{
public Guid Id { get; set; }
public string FirmName { get; set; }
}
Server-side usage
A controller can project EF Core entities directly to a ViewModel. When the result is intended for a remote grid, return an IQueryable<T> query and apply [Queryable].
[Authorize]
[Route("api/[controller]")]
public class FirmsController : LgControllerBase
{
private readonly ApplicationDbContext _db;
public FirmsController(ApplicationDbContext db)
{
_db = db;
}
[Queryable]
[HttpGet("GetFirmsByCountry")]
public IQueryable<VmCountryFirm> Get(QueryArg<int?> data)
{
// Projette l'entité EF Core vers le ViewModel exposé au client.
return _db.Firms.Where(c => c.CountryId == data.Value).Select(x => new VmCountryFirm
{
Id = x.Id,
FirmName = x.Name,
});
}
}
Best practices
| Topic | Recommendation |
|---|---|
| Location | ViewModels in Shared, conversions in application code on the server or model side. |
| Name | Prefix ViewModels with Vm. |
| Serialization | Use the serialization attributes expected by the project if the ViewModel travels between client and server. |
| Mapping | Centralize Model ↔ ViewModel conversions in explicit application code. |
| Queries | Project as IQueryable<T> when [Queryable] needs to apply filters, sorting, and pagination. |