Вложенный включает Entity Framework Core

Я использую EF Core для своего проекта. И у меня проблема с вложенным запросом в EF Core.

У меня 2 класса:

public class PermissionGroupDefinitionEntity : IEntity
{
    public string Name { get; set; }
    public string NormalizedName { get; set; }
    public string DisplayName { get; set; }

    public virtual ICollection<PermissionDefinitionEntity> PermissionDefinitions { get; set; }
}

public class PermissionDefinitionEntity : IEntity
{
    public string Name { get; set; }
    public string NormalizedName { get; set; }
    public string DisplayName { get; set; }

    public bool IsEnabled { get; set; }
    public virtual string GroupName { get; set; }

    public virtual PermissionGroupDefinitionEntity Group { get; set; }
    public virtual ICollection<PermissionDefinitionEntity> Children { get; set; }
}

и это ApplicationDbContext:

        builder.Entity<PermissionDefinitionEntity>().HasOne(r => r.Group).WithMany(r => r.PermissionDefinitions).OnDelete(DeleteBehavior.Cascade);
        builder.Entity<PermissionDefinitionEntity>().HasOne(r => r.Parent).WithMany(r => r.Children).OnDelete(DeleteBehavior.Cascade);

Я хочу запросить все PermissionGroupDefinitionEntity, включая PermissionDefinitionEntity, и самосылку на PermissionDefinitionEntity.

Могу ли я сделать это с EF Core?


person Minh Mít    schedule 11.07.2021    source источник
comment
Вы не можете, по крайней мере, в одном операторе LINQ. Это расширение дерева неизвестной глубины, требующее рекурсивного запроса. Или, если вам нужно все дерево, просто запросите все PermissionGroupDefinitions и PermissionDefinitions (удалите этот избыточный суффикс Entity), которые заполнят все свойства навигации.   -  person Gert Arnold    schedule 11.07.2021
comment
Итак, я должен использовать рекурсивные запросы? Спасибо за вашу поддержку.   -  person Minh Mít    schedule 11.07.2021
comment
Но не могли бы вы объяснить, как мне получить все дерево? Я не понимаю, зачем удалять суффикс Entity? Думаю, это просто название класса. @ Герт-Арнольд   -  person Minh Mít    schedule 11.07.2021
comment
stackoverflow.com/a/41837737/861716. Удаление суффикса - это всего лишь совет, он бесполезен и снижает удобочитаемость.   -  person Gert Arnold    schedule 11.07.2021
comment
Спасибо за ваше время. Я думаю, что буду использовать рекурсивные запросы для этой проблемы.   -  person Minh Mít    schedule 11.07.2021


Ответы (2)


Вам необходимо рекурсивно загрузить PermissionDefinitions, размещенные в PermissionGroupDefinitionEntity.

Во-первых, вы должны загрузить все PermissionGroupDefinitionEntities, включая его дочерние элементы, как в следующем запросе:

var query = _dbContext.PermissionGroupDefinitionEntity
            .AsNoTracking()
            .Include(p => p.PermissionDefinitions )
            .ThenInclude(p => p.Children)
            .ToListAsync();

Поскольку у каждого PermissionGroupDefinitionEntity есть список PermissionDefinition, вам нужны вложенные циклы, такие как следующий код:

foreach (var PermissionGroupDefinitionEntity in PermissionGroupDefinitionEntities)
{
    foreach (var PermissionDefinitions in PermissionDefinitions)
    {

    }
}

Затем во внутреннем цикле вы должны вызвать свою рекурсивную функцию. См. Следующую ссылку (образец для рекурсивного получения всех дочерних элементов в Entity Framework Core)

https://patrickdesjardins.com/blog/how-to-load-hierarchical-structure-with-recursive-with-entity-framework-5

У этого способа ужасная производительность, и я не рекомендую его.

В этом случае кажется, что вы должны написать процедуру хранения в sql для лучшей производительности.

person AmirhosseinSaloot    schedule 12.07.2021

Вы можете использовать .ThenInclude(i => ...) так

var query = _context.PermissionGroupDefinitionEntity
  .AsNoTracking()
  .Include(i => i.PermissionDefinitions)
      .ThenInclude(i => i.Group)
  .AsQueryable();

Редактировать:

var query = _context.PermissionGroupDefinitionEntity
  .AsNoTracking()
  .Include(i => i.PermissionDefinitions)
      .ThenInclude(i => i.Children)
  .AsQueryable();
person PancakeAlchemist    schedule 11.07.2021
comment
Спасибо за поддержку. Но когда я использую этот запрос. Я получил ошибку: System.InvalidOperationException: "Путь включения" PermissionDefinitions- ›Group" приводит к циклу. Циклы не допускаются в запросах без отслеживания; либо используйте запрос отслеживания, либо удалите цикл. '. И когда я удаляю AsNoTracking. Этот запрос возвращает только первый уровень PermissionDefinitions. - person Minh Mít; 11.07.2021
comment
О, я думаю, что неправильно прочитал вопрос, я отредактировал свой ответ, так что вы можете попробовать и посмотреть, решит ли это вашу проблему. - person PancakeAlchemist; 11.07.2021
comment
Спасибо за вашу поддержку. Этот запрос возвращает максимум двухуровневого определения PermissionDefinition. Как PermissionGroupDefinition = ›PermissionDefinition =› PermissionDefinition. Если у меня есть структура PermissionGroupDefinition = ›PermissionDefinition =› PermissionDefinition = ›PermissionDefinition, она не работает. - person Minh Mít; 11.07.2021