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

如何在EF Core查询PostgreSQL时为每条记录分配递增行序号

EF Core 搭配 PostgreSQL 实现查询阶段生成行号解决方案

共两种可行方案,可根据你的业务场景选择:

方案1:数据库服务器端生成行号(适合大数据量场景)

EF Core 7.0及以上版本原生支持PostgreSQL的ROW_NUMBER()窗口函数翻译,可直接在LINQ查询中实现行号生成,逻辑完全在数据库执行,无需拉取全量数据到内存:

var items = await Context.MyModelTable.AsNoTracking()
    // 必须指定排序规则,行号的生成顺序和该排序保持一致
    .OrderBy(tbl => tbl.Code)
    .Select(tbl => new 
    {
        Code = tbl.Code,
        Name = tbl.Name,
        // 调用EF内置函数生成行号,Over方法中指定和外层一致的排序规则
        Row = EF.Functions.RowNumber().Over(ob => ob.OrderBy(t => t.Code))
    })
    .ToListAsync();

该写法会被EF Core自动翻译为等效的PostgreSQL原生SQL,性能和手写SQL一致。如果你使用的EF Core版本低于7.0,也可以通过FromSqlRaw手写带ROW_NUMBER()的原生SQL实现相同效果。

方案2:内存层面生成行号(适合小数据量场景,写法更简单)

你之前认为内存处理无法保留匿名类型属于误区,直接调用LINQ to Objects提供的带索引的Select重载即可,全程无需定义额外实体类:

// 先查询基础数据到内存
var baseItems = await Context.MyModelTable.AsNoTracking()
    .OrderBy(tbl => tbl.Code)
    .Select(tbl => new 
    {
        tbl.Code,
        tbl.Name
    })
    .ToListAsync();
// 内存层面追加行号,依然使用匿名类型
var items = baseItems.Select((item, index) => new
{
    item.Code,
    item.Name,
    Row = index + 1
}).ToList();

该方案写法更简洁,不依赖EF版本和数据库类型,仅适合数据量不大的业务场景。

内容的提问来源于stack exchange,提问作者rodrigo.cantunes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.14 17:54:07