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

如何使用Entity Framework Core实现多表关联批量更新多行数据

Entity Framework Core 关联更新ProjectStep表ParentStepId实现方案

优先方案(EF Core 7.0及以上版本,纯Linq写法,性能最优)

EF Core 7开始提供了ExecuteUpdate/ExecuteUpdateAsync方法,支持直接在数据库端执行批量更新,生成的SQL逻辑和你手写的原生SQL一致,无需加载数据到内存:

// 假设context为你的DbContext实例
await context.ProjectSteps
    // 关联StepDefinition表
    .Join(
        context.StepDefinitions,
        ps => ps.StepDefinitionId,
        sd => sd.StepDefinitionId,
        (ps, sd) => new { CurrentPs = ps, Sd = sd }
    )
    // 关联父级ProjectStep表
    .Join(
        context.ProjectSteps,
        joinItem => joinItem.Sd.ParentStepId,
        parentPs => parentPs.StepDefinitionId,
        (joinItem, parentPs) => new { joinItem.CurrentPs, NewParentStepId = parentPs.ProjectStepId }
    )
    // 此处可追加你原SQL中省略的过滤条件,示例:.Where(x => x.CurrentPs.ProjectId == xxx)
    .ExecuteUpdateAsync(setters => setters
        .SetProperty(x => x.CurrentPs.ParentStepId, x => x.NewParentStepId)
    );

EF Core 6.0及更低版本方案

方案1:小数据量适用(内存加载后更新,Linq写法)

如果需要更新的数据量不大,可以先查询出匹配数据,遍历赋值后统一保存:

var updateList = await context.ProjectSteps
    .Join(
        context.StepDefinitions,
        ps => ps.StepDefinitionId,
        sd => sd.StepDefinitionId,
        (ps, sd) => new { CurrentPs = ps, Sd = sd }
    )
    .Join(
        context.ProjectSteps,
        joinItem => joinItem.Sd.ParentStepId,
        parentPs => parentPs.StepDefinitionId,
        (joinItem, parentPs) => new { joinItem.CurrentPs, NewParentStepId = parentPs.ProjectStepId }
    )
    // 此处追加过滤条件
    .ToListAsync();

foreach (var item in updateList)
{
    item.CurrentPs.ParentStepId = item.NewParentStepId;
}

await context.SaveChangesAsync();

方案2:大数据量适用(原生SQL执行,性能最优)

如果更新数据量较大,可直接执行你现有的SQL语句,避免内存开销:

// 有参数时建议使用ExecuteSqlInterpolatedAsync防止SQL注入
var affectedRows = await context.Database.ExecuteSqlRawAsync(@"
UPDATE  ps
SET     ParentStepId=ps1.ProjectStepId         
FROM    ProjectStep ps INNER JOIN
        StepDefinition sd ON ps.StepDefinitionId = sd.StepDefinitionId INNER JOIN
        ProjectStep AS ps1 ON sd.ParentStepId = ps1.StepDefinitionId
        -- 此处追加你的额外过滤条件
");

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 07:36:04