首页 > 解决方案 > Entity Framework Core 3.0 .Select() 不映射子对象

问题描述

我有两个表“产品”和“用户产品视图”,当用户查看产品时,会在“用户产品视图”表中插入带有产品 ID 的行,即使用户再次查看相同的产品。我的目标是向用户展示最近查看的产品。

原来我计划在“UserProductViews”表上使用 .GroupBy() 但根据我在 .Net Core 3.1 中的理解,我们不能直接在 dbcontext.UserProductViews 上使用 .GroupBy() 因为我需要先做 IEnumerable() 这不好对我来说,不能使用 .Distinct() 因为 'UserProductViews' 包含 Created Date 和 Modified Date 。然而,在尝试了很多方法后,我通过以下查询解决了它:

return _context.UserProductViews.Include(x => x.Product)
             .Include(x => x.Product.ProductTags)
             .Include(x => x.Product.ProductBrand)
             .Include(x => x.Product.ProductAttributes)
             .Include(x => x.Product.ProductMedia)
             .Include(x => x.Product.ProductVariants)
             .ThenInclude(x => x.ProductVariantAttributeValues)
             .Include(x => x.Product.Company)
             .Include(x => x.Product.Country)
             .Include(x => x.Product.ProductClassification)
             .Where(x =>
                x.UserId == userId
                && x.Product.Status == ProductStatus.Active
                && x.Product.ProductType == ProductType.Physical
                && x.Product.ProductMedia.Any())

        .Select(x => new RecentlyViewdProductResponse
        {
            Product = x.Product,
            UserProductViewId = x.UserProductViewId
        }).Distinct()
        .OrderByDescending(x => x.UserProductViewId)
        .AsNoTracking()
        .GetPagedAsync(page, pageSize);


public static async Task<PagedResult<T>> GetPagedAsync<T>(this IQueryable<T> query,
                                     int page, int pageSize) where T : class
    {
        var result = new PagedResult<T>();
        result.CurrentPage = page;
        result.PageSize = pageSize;
        result.RowCount = query.Count();


        var pageCount = (double)result.RowCount / pageSize;
        result.PageCount = (int)Math.Ceiling(pageCount);

        var skip = (page - 1) * pageSize;
        result.Results = await query.Skip(skip).Take(pageSize).ToListAsync();

        return result;
    }

我正在获取所有“userProductViews”并选择 userProductViews 的“产品”子对象(选择产品,以便我可以在产品上使用 .Distinct())和 userProductViews 的 ID(仅按其 ID 排序)

这里的问题是,如果我使用 .Select() 并将 userProductViews.product 映射到产品(它们是同一个类),那么产品的内部子对象不会与之映射。如图所示: 使用选择查询

但是,如果我删除 .Select() 并获得完整的“userProductViews”并转到其子“产品”,我可以看到它们包含在其中:没有选择查询

标签: c#linq.net-coreentity-framework-core

解决方案


尝试以下解决方案。在没有原始 SQL 的情况下,使用 EF Core 是我所能想象的最好的。

var latest = 
    from pv in _context.UserProductViews
    where pv.UserId == userId
        && pv.Product.Status == ProductStatus.Active
        && pv.Product.ProductType == ProductType.Physical
        && pv.Product.ProductMedia.Any()
    group pv by pv.ProductId into g
    select new 
    {
        ProductId = g.Key,
        UserProductViewId = g.Max(x => x.UserProductViewId)
    }

var productViews = _context.UserProductViews
    .Include(x => x.Product)
    .Include(x => x.Product.ProductTags)
    .Include(x => x.Product.ProductBrand)
    .Include(x => x.Product.ProductAttributes)
    .Include(x => x.Product.ProductMedia)
    .Include(x => x.Product.ProductVariants)
        .ThenInclude(x => x.ProductVariantAttributeValues)
    .Include(x => x.Product.Company)
    .Include(x => x.Product.Country)
    .Include(x => x.Product.ProductClassification));

var query = 
    from pv in productViews
    join q in latest on pv.UserProductViewId equals q.UserProductViewId
    orderby pv.UserProductViewId descending
    select new RecentlyViewdProductResponse
    {
        Product = pv.Product,
        UserProductViewId = pv.UserProductViewId
    };

return await query.GetPagedAsync(page, pageSize);

推荐阅读