Как я могу полностью загрузить рекурсивную модель на нескольких уровнях со структурой сущности? - PullRequest
1 голос
/ 22 апреля 2020

РЕДАКТИРОВАТЬ: Это ответ Возможен ли рекурсивный запрос в LINQ Он уже ответил, что, возможно, пропустил тот.

Я в сети. NET Core 2.2.

Я просмотрел несколько вопросов, заданных на этом сайте, и ни один из ответов не помог мне.

Моя модель выглядит так (упрощенно):

public class Product
{
    /// <summary>
    ///     Gets or sets the Id.
    /// </summary>
    public string Id { get; set; }

    /// <summary>
    ///     Gets or sets the code.
    /// </summary>
    public string Code { get; set; }

    /// <summary>
    ///     Gets or sets the properties.
    /// </summary>
    public List<Property> Properties { get; set; }

    /// <summary>
    ///     Gets or sets the products
    /// </summary>
    public List<Product> Products { get; set; }
}

public class Property
{
    /// <summary>
    ///     Gets or sets the Id.
    /// </summary>
    public string Id { get; set; }

    /// <summary>
    ///     Gets or sets the code
    /// </summary>
    public string Code { get; set; }
}

Я пытаюсь загрузить продукт со всеми его субпродуктами, включая свойства всех продуктов.

Во-первых, я смог загрузить все продукты рекурсивно, но, честно говоря, нет знаю, почему это работает.

Я пробовал это:

var products1 = this._context.Products.Where(x => x.Code == "TEST").Include(x => x.Products);

И он будет загружать только продукты первого уровня.

Тогда по счастливой случайности / ошибка Я оставил эту строку раньше вышеупомянутой:

this._context.Products.ToList()

Затем первая строка фактически рекурсивно загрузила все продукты ... хорошо, я думаю?

В любом случае, что теперь я? я пытаюсь сделать, это загрузить все продукты рекурсивно, а также загружает все их свойства .

Я пробовал несколько вещей, включая тенистый:

this._context.Products.Where(x => x.Code == "TEST").Include(x => x.Properties)
            .Include(x => x.Products).ThenInclude(x => x.Properties);

Но что бы я ни делал, я загружаю только свойства продуктов первого уровня рекурсии. Я по-прежнему полностью загружаю все продукты рекурсивно, но их свойства загружены только на первых двух уровнях.

Итак, в конечном счете, мой вопрос, как мне это сделать? В качестве дополнительного вопроса, на который можно ответить в любом случае, если ответ на реальный вопрос: зачем мне ставить эту строку:

this._context.Products.ToList()

перед этой строкой:

var products1 = this._context.Products.Where(x => x.Code == "TEST").Include(x => x.Products);

Чтобы загрузить продукты рекурсивно?

РЕДАКТИРОВАТЬ: обратите внимание, что я знаю, что могу рекурсивно загрузить весь товар / свойство с несколькими запросами (по одному для каждого товара) в al oop, но я определенно хочу избежать этого, если это возможно.

1 Ответ

1 голос
/ 22 апреля 2020

Стремительная загрузка не будет работать рекурсивно, но вы можете использовать отложенную загрузку. Это ухудшит вашу производительность, но вы сможете выполнять итерации всех слоев.

См. https://docs.microsoft.com/en-us/ef/core/querying/related-data

Самый простой способ использования отложенной загрузки это установка пакета Microsoft.EntityFrameworkCore.Proxies и включение его с помощью вызова UseLazyLoadingProxies. Например:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
    .UseLazyLoadingProxies()
    .UseSqlServer(myConnectionString);

Затем EF Core включит отложенную загрузку для любого свойства навигации, которое может быть переопределено, то есть оно должно быть виртуальным и в классе, который может быть унаследован. from.

Так что конвертируйте свои List s в виртуальные коллекции, и все будет хорошо go.

...