You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将LINQ查询转换为PostgreSQL原生SQL查询求助

将LINQ查询转换为PostgreSQL原生查询

你提供的LINQ逻辑核心是先统计每个条码的总出库量,再关联库存数据计算剩余可出库库存。下面直接给出对应的PostgreSQL原生查询,同时补充关键逻辑说明:

完整原生查询语句

用CTE(公共表表达式)实现分组统计,可读性和性能都更优:

WITH barcode_total_out AS (
    -- 先统计每个条码的总出库数量,对应LINQ里的barcodeQuantity
    SELECT 
        barcodenumber,
        SUM(quantity) AS total_out
    FROM barcode_post
    -- 这里要加你LINQ中barcodeSpec的过滤条件,比如时间范围、状态等
    -- WHERE ... 
    GROUP BY barcodenumber
)
SELECT 
    v.name AS vendor_name,
    -- 用COALESCE处理无出库记录的情况,把NULL转为0
    (md.quantity - COALESCE(bto.total_out, 0)) AS current_stock
FROM material_inward_barcodes mib
-- 关联库存详情表
JOIN material_inward_details md ON mib.productid = md.productid
-- 关联供应商表获取名称
JOIN vendors v ON mib.vendorid = v.id
-- 左连接出库统计,对应LINQ的DefaultIfEmpty()
LEFT JOIN barcode_total_out bto ON mib.barcode = bto.barcodenumber
-- 过滤剩余库存大于0的记录,同时指定供应商ID
WHERE (md.quantity - COALESCE(bto.total_out, 0)) > 0
  AND v.id = '你的供应商ID值'; -- 替换为实际传入的vendorId

关键细节说明

  • COALESCE:替代LINQ里的DefaultIfEmpty(),处理条码没有出库记录的场景,避免计算时出现NULL值。
  • 表/字段名:请根据你的PostgreSQL实际表名、字段名调整(PostgreSQL默认区分大小写,通常用小写+下划线命名规则)。
  • 过滤条件:记得把barcodeSpec对应的筛选逻辑补充到CTE的WHERE子句里。

优化后的EF Core LINQ查询(可选)

如果不想写原生SQL,也可以调整你的EF Core代码,让它自动生成高效的PostgreSQL查询:

public async Task<IList<VendorWiseStock>> GetVendorWiseStocksAsync(Guid vendorId)
{
    // 直接在EF里定义分组统计,避免先查内存再处理
    var barcodeOutStats = _dbContext.BarcodePost
        // 补充barcodeSpec的过滤条件
        // .Where(b => ...)
        .GroupBy(b => b.BarcodeNumber)
        .Select(g => new { BarcodeNumber = g.Key, TotalOut = g.Sum(b => b.Quantity) });

    var result = await (
        from barcodeData in _dbContext.MaterialInwardBarcodes
        join material in _dbContext.MaterialInwardDetails on barcodeData.ProductId equals material.ProductId
        join vendor in _dbContext.Vendors on barcodeData.VendorId equals vendor.Id
        // 左连接出库统计
        join stats in barcodeOutStats on barcodeData.Barcode equals stats.BarcodeNumber into statsGroup
        from stats in statsGroup.DefaultIfEmpty()
        where vendor.Id == vendorId
              && (material.Quantity - (stats?.TotalOut ?? 0)) > 0
        select new VendorWiseStock()
        {
            VendorName = vendor.Name,
            CurrentStock = material.Quantity - (stats?.TotalOut ?? 0)
        }).ToListAsync();

    return result;
}

内容的提问来源于stack exchange,提问作者Farhan Patel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 00:53:14