Linq中ToListAsync()和CountAsync()的区别
背景:一次在实现统计用户收藏数功能时,直接将展示”用户收藏“接口中的查询逻辑照搬下来,然后使用CountAsync()获取数量。结果发现这个数量和点进去查看”收藏“的数量不一样,统计的这个数量变多了,因为数据库有些关联的实体为null。原因在于使用Count操作即使写了Include也不会加载关联实体。
- 第一个片段包含了
.Include,这会增加查询复杂度
- 第二个片段即使写了
.Include也无效(因为Count操作不需要加载关联实体)
1 2
| _orderRepository.Query() .Where(o => o.OrderShipping != null && o.OrderShipping.WoodenBoxType != null)
|
1 2 3 4
| _orderRepository.Query() .Include(c => c.OrderShipping) .ThenInclude(os => os.WoodenBoxType) .Where(o => o.OrderShipping != null && o.OrderShipping.WoodenBoxType != null)
|
数据量大时采用哈希set或者dict字典
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| if (result.List.Count() > 0) { var qualityIdList = result.List .SelectMany(p => p.Items ?? Enumerable.Empty<CustomerOrderItemQueryResult>()) .Select(p => p.QualityId) .Distinct() .ToList();
// 使用 HashSet 提高查询效率 var qualityIdHashSet = new HashSet<int>(qualityIdList); var qualityService = await _qualityService .Query(p => qualityIdHashSet.Contains(p.Id)) .ToListAsync();
//转成字典 var qualityServiceDict = qualityService.ToDictionary(q => q.Id, q => q);
foreach (var item in result.List.Where(x => x.Items?.Count() > 0)) { foreach (var t in item.Items) { if (qualityServiceDict.TryGetValue(t.QualityId, out var quality)) { t.QualityName = quality.Name; t.QualityYear = quality.Year; } } } }
|