【问题标题】:LINQ query WHERE SUM is greater than a numberLINQ 查询 WHERE SUM 大于数字
【发布时间】:2026-02-14 18:20:06
【问题描述】:

我在数据库中映射了仓库中的一系列货架。架子本身包含以立方英尺为单位测量的盒子。我想执行查询并过滤掉货架上最小立方英尺的位置。我能够运行显示可用空间量的查询,但是用于限制SUM 结果的WHERE 子句似乎没有任何效果。

这是我获取所有货架及其可用空间和总空间的查询:

Dim shelves As IQueryable(Of Location) = _db.Locations.Include(Function(l) l.Boxes)
    .Select(Function(loc) New With 
    {
        .LocationID = loc.LocationID,
        .WarehouseID = loc.WarehouseID,
        .Warehouse = loc.Warehouse.Name,
        .Row = loc.Row, 
        .Column = loc.Column, 
        .Bunk = loc.Bunk,
        .TotalSpace = loc.Footage,
        .FreeSpace = (loc.Footage - loc.Boxes.Select(Function(s) s.Size).DefaultIfEmpty(0).Sum()) 
     }).ToList()

这将为每个位置返回正确的值,包括正确的可用空间量。当我引入WHERE 子句时,它没有任何作用。这是我的查询,其中包含 WHERE 子句:

Dim shelves As IQueryable(Of Location) = _db.Locations.Include(Function(l) l.Boxes)
    .Where(Function(l) (l.Boxes.Select(Function(e) e.Size).DefaultIfEmpty(0).Sum() >= EmptySpace))
    .Select(Function(loc) New With 
    {
        .LocationID = loc.LocationID,
        .WarehouseID = loc.WarehouseID,
        .Warehouse = loc.Warehouse.Name,
        .Row = loc.Row, 
        .Column = loc.Column, 
        .Bunk = loc.Bunk,
        .TotalSpace = loc.Footage,
        .FreeSpace = (loc.Footage - loc.Boxes.Select(Function(s) s.Size).DefaultIfEmpty(0).Sum()) 
     }).ToList()

由于.FreeSpace 返回正确的值,我不确定为什么它不能在我的WHERE 子句中按相同的值进行过滤。

【问题讨论】:

    标签: asp.net vb.net entity-framework linq


    【解决方案1】:

    更新

    你原来的Where谓词

    .Where(Function(l) (l.Boxes.Select(Function(e) e.Size).DefaultIfEmpty(0).Sum() >= EmptySpace))
    

    没有计算可用空间,这就是它没有效果的原因。

    您会注意到,在您最初的选择中,您计算​​的可用空间为

    (loc.Footage - loc.Boxes.Select(Function(s) s.Size).DefaultIfEmpty(0).Sum())
    

    通知 loc.Footage 在 Where 谓词中丢失。

    这意味着这个更新后的查询应该可以工作

    Dim shelves As IQueryable(Of Location) = _db.Locations.Include(Function(l) l.Boxes)
        .Where(Function(loc) (loc.Footage - loc.Boxes.Select(Function(s) s.Size).DefaultIfEmpty(0).Sum()) >= EmptySpace)
        .Select(Function(loc) New With 
        {
            .LocationID = loc.LocationID,
            .WarehouseID = loc.WarehouseID,
            .Warehouse = loc.Warehouse.Name,
            .Row = loc.Row, 
            .Column = loc.Column, 
            .Bunk = loc.Bunk,
            .TotalSpace = loc.Footage,
            .FreeSpace = (loc.Footage - loc.Boxes.Select(Function(s) s.Size).DefaultIfEmpty(0).Sum()) 
         }).ToList()
    

    原答案

    尝试在选择后对投影对象应用过滤器

    Dim shelves As IQueryable(Of Location) = _db.Locations.Include(Function(l) l.Boxes)    
    .Select(Function(loc) New With 
    {
        .LocationID = loc.LocationID,
        .WarehouseID = loc.WarehouseID,
        .Warehouse = loc.Warehouse.Name,
        .Row = loc.Row, 
        .Column = loc.Column, 
        .Bunk = loc.Bunk,
        .TotalSpace = loc.Footage,
        .FreeSpace = (loc.Footage - loc.Boxes.Select(Function(s) s.Size).DefaultIfEmpty(0).Sum()) 
     })
    .Where(Function(loc) loc.FreeSpace >= EmptySpace)
    .ToList()
    

    这样,空闲空间已经被计算出来并包含在匿名对象中。

    【讨论】:

    • 谢谢,这行得通。我的程序是一次只返回 20 个结果的 Web API 控制器的一部分。这比没有 where 子句的查询运行得慢很多,但这是可以理解的,因为它必须计算数百万立方英尺的可用空间才能返回结果。你能想出提高性能的方法吗?
    • @Nse 我现在只看到你的消息。你有没有弄清楚你在哪里犯了 where 子句的错误?我想我刚刚看到了您的 where 过滤器中省略的内容。
    最近更新 更多