c# - 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”并转到其子“产品”,我可以看到它们包含在其中:没有选择查询
解决方案
尝试以下解决方案。在没有原始 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);
推荐阅读
- file - 逻辑记录大小是否以匹配现有物理记录大小的方式确定?为什么/为什么不?
- html - Bootstrap vue卡底部按钮对齐
- typescript - 用于 Typescript 的 Sonarqube 上未显示代码覆盖率
- actor - 将传感器倒置
- input - MPI 读取简单的数据框或 txt 文件
- html - 我应该如何保存到数据库?
- docker - Docker-Compose:如何将 Docker 机器 IP 地址传递给服务
- javascript - 如何获取和显示 blob 图像
- c - 有没有办法在调用工具链时覆盖定义语句?
- cassandra - 重复的 Cassandra SSTable 文件