V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
edis0n0
V2EX  ›  .NET

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

  •  
  •   edis0n0 · 2023-03-09 09:12:56 +08:00 · 1959 次点击
    这是一个创建于 658 天前的主题,其中的信息可能已经有所发展或是发生改变。
    _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()
    
    5 条回复    2023-03-09 10:56:23 +08:00
    zhzhwcn
        1
    zhzhwcn  
       2023-03-09 09:24:31 +08:00
    把生成的 sql 打印到日志里 然后把参数也记录下来 手动执行一下
    ColinZeb
        2
    ColinZeb  
       2023-03-09 09:33:06 +08:00   ❤️ 3
    1.自定义模型时不需要 Include,如题目中 Select 时使用了匿名对象
    2.判断导航属性不为空时最好使用外键,例如:x.GoodId.HasValue ,不确定 Sql 解释器是否会优化这个操作
    3.复杂查询时不要直接 ToList,先把 IQueryable<T>赋值给临时变量,调试时可以看到 IQueryable 有一个 DebugView 属性,里面可以看到带参数的 Sql ,以及 Linq 表达式树用于调试。
    4.如果要记录到日志可以使用 IQueryable 的 ToQueryString 扩展方法,内容等同于 DebugView.Sql
    edis0n0
        3
    edis0n0  
    OP
       2023-03-09 09:46:43 +08:00
    @ColinZeb #2 include 后 where 是为了把已经删除的商品排除掉。有什么更好的办法吗?
    ColinZeb
        4
    ColinZeb  
       2023-03-09 10:06:32 +08:00
    @edis0n0 #3 我说的是不需要,像你这个表达式最后用的匿名对象,最后查询的东西并没有 Good,所以 Include 是无效的,写不写没区别。
    Include 只在 ToList 时加载导航属性时有效,IQueryable 里写表达式调用任何东西都不需要 Include 。
    jvCrystal
        5
    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 看下面的查询。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5229 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 03:47 · PVG 11:47 · LAX 19:47 · JFK 22:47
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.