Сведите многие к одному с помощью динамического linq

#entity-framework-6 #dynamic-linq #dynamic-linq-core

Вопрос:

У меня есть три модели, которые необходимо включить в отчет:

 public partial class Chimney
{
    public int Id { get; set;}
    public string Name { get; set; }
    public string Code { get; set; }
    public int IndustrialUnitId { get; set; }
    public IndustrialUnit IndustrialUnit { get; set; }
}
public partial class IndustrialUnit
{
    public int Id { get; set;}
    public string Code { get; set; }
    public string UnitName { get; set; }
    public string CompanyName { get; set; }
}
public partial class InspectionReport : BaseEntity
{
    public string BusinessUnitName { get; set; }
    public int UnitTypeId { get; set; }
    public int? IndustrialUnitId { get; set; }
    public IndustrialUnit IndustrialUnit { get; set; }
}
 

В динамическом построителе отчетов в моем веб-приложении пользователи выбирают сущность, и после этого для выбора полей этой сущности для создания отчета пользователю будет показана структура узлов дерева. Дерево показывает поля сущности, ее родителей и потомков во вложенной форме.
Для примера, для приведенных выше моделей, если пользователь выберет дымоход для получения отчетов, IndustrialUnit и его дочерние элементы (например, InspectionReport) появятся в узлах дерева.

После этого функция используется для создания запроса с динамическим Linq, который получает сущность в качестве параметра и создает для этой сущности плоский запрос.

 public static IQueryable ApplyFlattenProjection( Projection projection)
{
    var entities = this.Context.GetDatas(entityType);
    string select = string.Join(",", entities.ElementType.GetProperties().Where(x => !x.GetCustomAttributes(typeof(NotMappedAttribute)).Any()).Select(x => $"{x.Name} As {x.Name}"));
    entities = entities.Select($"new(new({select}) As {projection.EntityType.Name})");
    entities = entities.GetFlattenProjection(projection);
    return entities;
}

internal static IQueryable GetFlattenProjection(this IQueryable queryable, Projection root)
{
     .
     .
     .
     var fieldName="IndutrialUnit.InspectionReports";

     queryable = queryable.SelectMany($"{fieldName}.DefaultIfEmpty()", $"new(param2 as 
                {fieldName},{selector}param1. 
                {root.EntityType.Name} as {root.EntityType.Name})", "param1", "param2");
     .
     .
     .
}
 

в этом коде SelectMany создает исключение, поскольку IndustrialUnit не является коллекцией и является объектом. Как можно было бы решить эту проблему?