簡體   English   中英

LINQ查詢以獲取遞歸類別結構和每個類別的乘積

[英]LINQ query to get recursive category structure and products of each category

如何重寫查詢以將每個類別的所有產品包括在遞歸產品類別樹中? 該查詢獲取類別及其子級,因此我只缺少產品:

var categories = _context.ProductCategories
                .Include(e => e.Children)
                .Where(e => e.ParentId == null)
                .ToList();

實體模型:

public class ProductCategory
{
    public int Id { get; set; }
    public int SortOrder { get; set; }
    public string Title { get; set; }
    [ForeignKey(nameof(ParentCategory))]
    public int? ParentId { get; set; }
    // Nav.props:
    public ProductCategory ParentCategory { get; set; }
    public ICollection<ProductCategory> Children { get; set; }
    public List<ProductInCategory> ProductInCategory { get; set; }
}

public class ProductInCategory
{
    public int Id { get; set; }
    public int ProductId { get; set; }
    public int SortOrder { get; set; }
    public int ProductCategoryId { get; set; }
    // Nav.props:
    public Product Product { get; set; }
    public ProductCategory ProductCategory { get; set; }
}

public class Product
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Info { get; set; }
    public decimal Price { get; set; }
    // Nav.props:
    public List<ProductInCategory> InCategories { get; set; }
}

視圖模型:

public class ViewModelProductCategory
{
    public int Id { get; set; }
    public int? ParentId { get; set; }
    public string Title { get; set; }
    public int SortOrder { get; set; }

    public string ProductCountInfo
    {
        get
        {
            return Products != null && Products.Any() ? Products.Count().ToString() : "0";
        }
    }
    public ViewModelProductCategory ParentCategory { get; set; }
    public IEnumerable<ViewModelProductCategory> Children { get; set; }
    public IEnumerable<ViewModelProduct> Products { get; set; }
}

我正在使用AutoMapper將查詢結果轉換為viewmodel。

這是我嘗試渲染的方式:

索引視圖:

@model IEnumerable<MyStore.Models.ViewModels.ViewModelProductCategory>

<ul style="list-style:none;padding-left:0px;">
    @Html.Partial("_CategoryAndProductRecursive", Model)
</ul>

_CategoryAndProductRecursive.cshtml:

@model IEnumerable<MyStore.Models.ViewModels.ViewModelProductCategory>
<ul>
@if (Model != null)
{
    foreach (var item in Model)
    {
    <li>
    @item.Title
        <ul style="list-style:none;">
        @Html.Partial("_CategoryAndProductRecursive.cshtml", item.Children)
        @if (item.Products != null)
        {
            @foreach (var product in item.Products)
            {
                <li>@product.Title</li>
            }
        }
        </ul>
    </li>
    }
}
</ul>

EF核心查詢部分實際上有兩個獨立的問題。

首先是如何急於加​​載ProductCategory.ProductInCategoryProductInCategory.Product導航屬性。 答案很簡單-使用Include / ThenInclude`,如文檔的“ 加載相關數據 - 急切加載”部分所述。

第二個是如何為ProductCategory.Children遞歸地執行該操作。 技巧是強制將整個 ProductCategory樹加載到內存中,從而讓EF Core導航屬性fixup進行父/子實體鏈接, 然后過濾根實體。

var categories = _context.ProductCategories
    .Include(e => e.ProductInCategory)
        .ThenInclude(e => e.Product)
    .AsEnumerable() // <-- Force full execution (loading) of the above
    .Where(e => e.ParentId == null) // <-- then apply the root filter
    .ToList();

請注意,在此過程中我們不需要包括Children 請注意,某些Children集合將為null 如果這是一個問題,只需確保您在構造函數中或使用初始化程序初始化它們即可。

public ICollection<ProductCategory> Children { get; set; } = new List<ProductCategory>();

您可以嘗試使用Load而不是Include and loop進行預定義的次數來每次加載子代。

https://msdn.microsoft.com/zh-CN/library/bb896249.aspx

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM