steveski / Perigee.Framework

CQRS Framework for developing .NET applications. Compiled as a suite of .NET Standard libraries allowing use in a variety of .NET language versions

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Support required for ThenInclude

daz-codersoft opened this issue · comments

Include was implemented. ThenInclude is also required in the framework. This would be used something like:

var includes = new List<Expression<Func<Entities.Order, object>>>
{
    x => x.orderProductMappings,
    x => new Expression<Func<Entities.OrderProductMapping, object>>
    {
        y=>y.product,
    }
};

To make this work, the includes logic in QueryUnfiltered in EntityDbContext would probably need updating to a while loop for the look ahead:

var expression = includes.begin();
while (expression != includes.end()
{
    var furtherIncludableQuery = query.Include(expression);
    expression++;
    if (expression != includes.end())
    {
        if (expression is Expression<Func<TEntity, TProperty>> thenInclude)
        {
            query = furtherIncludableQuery.ThenInclude (thenInclude);
        }
        else
        {
            query = furtherIncludableQuery;
        }
    }
}

Here's the algorithm re-written to "work":

            var numItems = includes.Count();
            int currentItem = 0;
            while (currentItem < numItems)
            {
                var furtherIncludableQuery = query.Include(includes.ElementAt(currentItem));
                currentItem++;
                if (currentItem < numItems)
                {
                    if (includes.ElementAt(currentItem) is Expression<Func<TEntity, TProperty>> thenInclude)
                    {
                        query = furtherIncludableQuery.ThenInclude(thenInclude);
                    }
                    else
                    {
                        query = furtherIncludableQuery;
                    }
                }
            }

However it doesn't compile. The .ThenInclude line isn't valid. Any thoughts?

OK, i think I now understand the problem...but don't yet know how to code the solution.

If QueryUnfiltered had an extra templated type, so the includes list is a list of
Expression<Func<TEntity, TProperty1, TProperty2>>
(note the extra Property)
If TProperty2 is not null, get the first 2 templated arguments to create a
Expression<Func<TEntity, TProperty>>
and pass it to .Include.
Otherwise pass it to .ThenInclude.

So the list would be created with either:
x=>x.address
or
x=>x.address.country

(this would support address having an attribute "countryId", which does a lookup to find the country name)

Not sure if this will work or not, but I think it's a way ahead.