请 V 友帮忙看看 EF Core 这样统计商品的订单状态为什么取到的都是空 List,排查了一晚上。确定 Where 是正确的。

2023-03-09 09:12:56 +08:00
 edis0n0
_context.Orders.Where(x => x.CreatedAt >= DateTimeOffset.FromUnixTimeMilliseconds(filter.TimeFrom) && x.CreatedAt <= DateTimeOffset.FromUnixTimeMilliseconds(filter.TimeTo))
            .Include(x => x.Good).Where(x => x.Good != null)
            .GroupBy(o => o.GoodId)
            .Select(g => new
            {
                GoodId = g.Key,
                GoodName = _context.Goods.AsNoTracking().FirstOrDefault(x => x.GoodId == g.Key).Name,
                Delivery = g.Count(o => o.Status == (int) OrderStatusEnum.Delivery),
                Cancelled = g.Count(o => o.Status == (int) OrderStatusEnum.Cancelled),
                InReview = g.Count(o => o.Status == (int)OrderStatusEnum.InReview),
                Total = g.Count()
            })
            .ToList()
1930 次点击
所在节点    .NET
5 条回复
zhzhwcn
2023-03-09 09:24:31 +08:00
把生成的 sql 打印到日志里 然后把参数也记录下来 手动执行一下
ColinZeb
2023-03-09 09:33:06 +08:00
1.自定义模型时不需要 Include,如题目中 Select 时使用了匿名对象
2.判断导航属性不为空时最好使用外键,例如:x.GoodId.HasValue ,不确定 Sql 解释器是否会优化这个操作
3.复杂查询时不要直接 ToList,先把 IQueryable<T>赋值给临时变量,调试时可以看到 IQueryable 有一个 DebugView 属性,里面可以看到带参数的 Sql ,以及 Linq 表达式树用于调试。
4.如果要记录到日志可以使用 IQueryable 的 ToQueryString 扩展方法,内容等同于 DebugView.Sql
edis0n0
2023-03-09 09:46:43 +08:00
@ColinZeb #2 include 后 where 是为了把已经删除的商品排除掉。有什么更好的办法吗?
ColinZeb
2023-03-09 10:06:32 +08:00
@edis0n0 #3 我说的是不需要,像你这个表达式最后用的匿名对象,最后查询的东西并没有 Good,所以 Include 是无效的,写不写没区别。
Include 只在 ToList 时加载导航属性时有效,IQueryable 里写表达式调用任何东西都不需要 Include 。
jvCrystal
2023-03-09 10:56:23 +08:00
建议如果找不到原因,可以分两步去处理
①、_context.Orders.Where(x => x.CreatedAt >= DateTimeOffset.FromUnixTimeMilliseconds(filter.TimeFrom) && x.CreatedAt <= DateTimeOffset.FromUnixTimeMilliseconds(filter.TimeTo))
.Include(x => x.Good).Where(x => x.Good != null)
先把这个处理好,而且建议改写一下
_context.Orders.Include(x => x.Good).Where(x => x.CreatedAt >= DateTimeOffset.FromUnixTimeMilliseconds(filter.TimeFrom) && x.CreatedAt <= DateTimeOffset.FromUnixTimeMilliseconds(filter.TimeTo)).tolist();

第一步如果有数据去除掉 tolist ,再去 group 看下面的查询。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/922459

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX