Tree View

If your application calls for it, you can display the hierarchy in a single view. You probably wouldn't do this for a blog application, but I'll demonstrate how this is done.

Define a specification that starts at the top level, in this case the creator User of the sites. Then extend that specification with child specifications in the select clause. Continue for as many levels as you would like to display in the tree.

var sitesAndPostsByUser = 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,
        Domains =
            from domain in facts.OfType<SiteDomain>()
            where domain.site == site
            where !facts.Any<SiteDomain>(next => next.prior.Contains(domain))
            select domain.value,
        Posts =
            from post in facts.OfType<Post>()
            where post.site == site
            where !facts.Any<PostDeleted>(pd => pd.post == post &&
                !facts.Any<PostRestored>(pr => pr.deleted == pd))
            select new
            {
                Post = post,
                Title =
                    from title in facts.OfType<PostTitle>()
                    where title.post == post
                    where !facts.Any<PostTitle>(next => next.prior.Contains(title))
                    select title.value
            }
    });

var sitesAndPosts = await jinagaClient.Query(sitesAndPostsByUser, user);

sitesAndPosts

Create a hierarchical view model by selecting the child view models from the child objects.

var sitesAndPostsViewModel = sitesAndPosts.Select(s => new
{
    Name = s.Names.FirstOrDefault() ?? "New site",
    Domain = s.Domains.FirstOrDefault() ?? "",
    Posts = s.Posts.Select(p => new
    {
        Title = p.Title.FirstOrDefault() ?? "New post"
    })
});

sitesAndPostsViewModel

The hierarchical pattern described here works for models that have different kinds of objects at each level. If you have a hierarchy that have the same kinds of objects at various levels -- such as folders that contain folders, or employees who manage other employees -- then the pattern is different. We will discuss that elsewhere.

Continue With

Workflow

Jinaga is a product of Jinaga LLC.

Michael L Perry, President