将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
相关产品推荐
相关产品推荐

