如何使用多个 Id 运行 EF Core ExecuteUpdate,每个 Id 使用不同的条件

问题描述 投票:0回答:2

我在 for 循环中调用了下面的

ExecuteUpdate
,我想知道是否可以消除
For
循环并将
ExecuteUpdate
作为一次调用运行?

foreach (var registrant in yogabandEvent.Registrants) 
{
    result = await _dbContext.Users
        .Where(p => p.Id == registrant.UserId)
    .ExecuteUpdateAsync(setters => setters
        .SetProperty(p => p.Attended, registrant.RegistrantType == RegistrantType.Student ? p => p.Attended + 1 : p => p.Attended)
        .SetProperty(p => p.Hosted, (registrant.RegistrantType == RegistrantType.Host || registrant.RegistrantType == RegistrantType.HostInstructor) ? p => p.Hosted + 1 : p => p.Hosted)
        .SetProperty(p => p.Instructed, registrant.RegistrantType == RegistrantType.Instructor ? p => p.Instructed + 1 : p => p.Instructed)
    );
}
c# .net linq entity-framework-core linq-to-entities
2个回答
0
投票

ExecuteUpdate
生成一条发送到数据库的更新语句。因此,不可能使用复杂的本地数据,例如
yogabandEvent.Registrants
,这些数据应该在语句运行时读取,因此无法消除循环。

但是,在您的情况下,可以轻松地重组更新以创建一个完成这项工作的更新语句。由于您只更新

Users
,其中
yogabandEvent.Registrants
的类型为
Student
,因此您可以先收集这些 Id 并在更新语句中使用
Contains

var studentIds = yogabandEvent.Registrants
    .Where(r => r.RegistrantType == RegistrantType.Student)
    .Select(r => r.UserId)
    .ToList();

result = await _dbContext.Users
               .Where(p => studentIds.Contains(p.Id))
               .ExecuteUpdateAsync(setters => setters
                   .SetProperty(p => p.Attended, p => p.Attended + 1));


0
投票

我关注了一个用户帖子,该帖子已被删除,但为我提供了我正在寻找的内容,所以我将发布我自己问题的解决方案。您可以在下面看到,现在我可以提供一个没有 for 循环的单个调用,该调用在每个

SetProperty
内都有可应用于 ID 列表的条件,从而消除任何 for 循环或执行多个
ExecuteUpdate
调用。

 var studentIds = yogabandEvent.Registrants
    .Where(x => x.RegistrantType == RegistrantType.Student)
 .Select(x => x.UserId);

 var hostId = 1;          
 var instructorId = 2

 result = await _dbContext.Users
    .Where(p => yogaClass.Registrants.Select(x => x.UserId).Contains(p.Id))
 .ExecuteUpdateAsync(setters => setters
    .SetProperty(p => p.Attended, p => p.Attended + (studentIds.Contains(p.Id) ? 1 : 0))
    .SetProperty(p => p.Hosted, p => p.Hosted + (p.Id == hostId ? 1 : 0))
    .SetProperty(p => p.Instructed, p => p.Instructed + (p.Id == instructorId ? 1 : 0))
);
© www.soinside.com 2019 - 2024. All rights reserved.