score:1

As mentioned in comments, currently it's not possible to create a recursive expandable (i.e. non invokable) expression.

However, if you can limit the maximum depth, one possible solution would be to build expression like this (utilizing the EF navigation property):

Parents = new MyTable [] { x.Parent, x.Parent.Parent, x.Parent.Parent.Parent, ...}
    .Where(e => e != null)

dynamically:

static Expression<Func<MyTable, IEnumerable<MyTable>>> ParentsSelector(int maxLevels)
{
    var parameter = Expression.Parameter(typeof(MyTable), "x");
    var parents = new Expression[maxLevels];
    for (int i = 0; i < parents.Length; i++)
        parents[i] = Expression.Property(i > 0 ? parents[i - 1] : parameter, "Parent");
    Expression<Func<MyTable, bool>> predicate = x => x != null;
    var result = Expression.Call(
        typeof(Enumerable), "Where", new[] { parameter.Type },
        Expression.NewArrayInit(parameter.Type, parents), predicate);
    return Expression.Lambda<Func<MyTable, IEnumerable<MyTable>>>(result, parameter);
}

and use it as follows:

var parents = ParentsSelector(10);
var query = dbContext.MyTable
    .AsExpandable()
    .Where(x => x.Id == myId)
    .Select(x => new
    {
        Parents = parents.Invoke(x)
    });

Related Articles