簡體   English   中英

"Entity Framework Core 批量更新底層集合"

[英]Entity Framework Core bulk update underlying collections

是否有 Entity Framework Core 的已知擴展可以像此 SqlRaw 示例中那樣執行此批量更新?

dbc.Database.ExecuteSqlRawAsync(
            "UPDATE [Assembly] SET OnHold = @OnHold, UpdatedWith = @UpdatedWith, UpdatedAt = @UpdatedAt, UpdatedById = @UpdatedById FROM [Assembly] INNER JOIN Station ON [Assembly].StationID = Station.ID INNER JOIN Project ON Station.ProjectID = Project.ID WHERE Project.ID = @ProjectID",
            onHold, updatedWith, updatedAt, updatedById, projectID)

我會建議linq2db.EntityFrameworkCore<\/a> (免責聲明:我是創作者之一)

然后您可以執行以下操作:

var updateQuery =
    from a in ctx.Assembly
    join s in ctx.Station on a.SationId equals s.ID
    join p in ctx.Project on s.ProjectId equals p.ID
    where p.ID == projectId
    select a;

var recordsAffected = await updateQuery
    .Set(a => a.OnHold, onHold)
    .Set(a => a.UpdatedWith, updatedWith)
    .Set(a => a.UpdatedAt, a => Sql.CurrentTimeStamp)
    .Set(a => a.UpdatedById, updatedById)
    .UpdateAsync();

Entity Framework Core 5.0 中引入的IQueryable.ToQueryString方法可能有助於減少/簡化代碼中使用的原始 SQL。 此方法將生成可包含在原始 SQL 查詢中的 SQL,以對該查詢標識的記錄執行批量更新。

例如:

var query =
    from a in dbc.Assembly
    join s in dbc.Station on a.StaionId equals s.Id
    join p in dbc.Project on s.ProjectId equals p.Id
    where p.Id == projectId
    select a.Id;

var sql = $@"
    UPDATE Assembly
    SET OnHold = {{0}}, UpdatedWith = {{1}}, UpdatedAt = {{2}}, UpdatedById = {{3}}
    WHERE Id IN ({query.ToQueryString()})
";

dbc.Database.ExecuteSqlRawAsync(sql, onHold, updatedWith, updatedAt, updatedById);

這種方法的主要缺點是使用原始 SQL。 但是,我不知道有任何合理的方法可以通過當前的 Entity Framework Core 功能來避免這種情況 - 你被這個警告所困擾,或者在另一個答案中提到的引入對另一個庫(如linq2db.EntityFrameworkCore )的依賴的警告here。

如果(何時)將來解決以下問題,那么我們可能會對這個問題有更好的答案: Bulk (ie set-based) CUD operations (without loading data into memory) #795

稍有耐心,EFCore 中將提供內置的BulkUpdate()BulkDelete方法,這些方法將在 EFCore 7.0 中提供

context.Customers.Where(...).BulkDelete();
context.Customers.Where(...).BulkUpdate(c => new Customer { Age = c.Age + 1 });
context.Customers.Where(...).BulkUpdate(c => new { Age = c.Age + 1 });

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM