- Modeling
- Entities
Projections
To populate a user interface, a specification will need to add details to its results.
To accomplish this, create an object in the select
clause.
The object can include properties that are computed from child specifications.
For the blog application, we'll want to display a list of sites.
The user will need to see the name of each site in the list.
Let's modify the sitesByUser
specification to include the names of each site.
var sitesByUser = Given<User>.Match((user, facts) =>
from site in facts.OfType<Site>()
where site.creator == user
where !facts.Any<SiteDeleted>(
sd => sd.site == site &&
!facts.Any<SiteRestored>(sr => sr.deleted == sd))
select new
{
Site = site,
Names =
from name in facts.OfType<SiteName>()
where name.site == site
where !facts.Any<SiteName>(next => next.prior.Contains(name))
select name.value
});
var sites = await jinagaClient.Query(sitesByUser, user);
sites
index | value |
---|
0 | { Site = Site { creator = Jinaga.User, createdAt = 5/18/2024 5:54:05 PM }, Names = System.Linq.Enumerable+<OfTypeIterator>d__66`1[System.String] }
|
Site | Site { creator = Jinaga.User, createdAt = 5/18/2024 5:54:05 PM }
|
creator | Jinaga.User
| createdAt | 2024-05-18 17:54:05Z |
| Names | [ My Journal ]
|
|
With this structure, the user interface can generate a list of sites.
The Names
property is going to be a collection of names, not a single value.
The user interface might use FirstOrDefault
to turn it into a single value.
var sitesViewModel = sites.Select(s => new
{
Name = s.Names.FirstOrDefault() ?? "New site"
});
sitesViewModel
index | value |
---|
0 | { Name = My Journal }
|
Continue With
Additional Mutable Properties