如何使用EF Core对API同步的用户实现软删除?
实现软删除并同步第三方API用户数据的方案
1. 更新实体类,添加软删除标记字段
首先给User实体补充when_deleted字段,类型设为可空DateTime?——未删除时该值为null,标记删除时赋值为当前时间:
public class User { public int id { get; set; } public string name { get; set; } public string username { get; set; } public string email { get; set; } public string phone { get; set; } public DateTime? when_deleted { get; set; } // 新增软删除标记字段 }
2. 配置EF Core全局查询过滤器
在你的DbContext的OnModelCreating方法中,给User实体添加全局查询过滤器,确保默认查询只会返回未被软删除的用户:
protected override void OnModelCreating(ModelBuilder modelBuilder) { // 全局过滤已软删除的用户 modelBuilder.Entity<User>() .HasQueryFilter(u => u.when_deleted == null); }
如果需要查询所有用户(包括已软删除的),可以使用IgnoreQueryFilter()绕过过滤器:
var allUsers = await dbContext.Users.IgnoreQueryFilter().ToListAsync();
3. 实现API同步逻辑(核心)
在后台服务中,按照以下逻辑同步第三方API的用户数据,处理新增、更新和软删除:
public async Task ExecuteAsync(CancellationToken stoppingToken) { while (!stoppingToken.IsCancellationRequested) { // 调用第三方API获取最新用户列表 var apiUsers = await _httpClient.GetFromJsonAsync<List<User>>("https://第三方API地址", stoppingToken); if (apiUsers == null) { await Task.Delay(TimeSpan.FromMinutes(5), stoppingToken); continue; } var apiUserIds = apiUsers.Select(u => u.id).ToHashSet(); using var scope = _serviceProvider.CreateScope(); var dbContext = scope.ServiceProvider.GetRequiredService<YourDbContext>(); // 获取本地所有未软删除的用户 var localUsers = await dbContext.Users.ToListAsync(stoppingToken); // 1. 软删除本地存在但API中已移除的用户 var usersToSoftDelete = localUsers.Where(u => !apiUserIds.Contains(u.id)).ToList(); foreach (var user in usersToSoftDelete) { user.when_deleted = DateTime.UtcNow; // 使用UTC时间避免时区问题 } // 2. 处理新增和更新用户 foreach (var apiUser in apiUsers) { var localUser = localUsers.FirstOrDefault(u => u.id == apiUser.id); if (localUser == null) { // 新增用户,默认when_deleted为null(未删除) dbContext.Users.Add(apiUser); } else { // 更新用户基础信息 localUser.name = apiUser.name; localUser.username = apiUser.username; localUser.email = apiUser.email; localUser.phone = apiUser.phone; // 如果用户之前被软删除,现在API中又出现则恢复(重置标记) if (localUser.when_deleted != null) { localUser.when_deleted = null; } } } // 保存所有变更到数据库 await dbContext.SaveChangesAsync(stoppingToken); // 设置同步间隔,示例为5分钟 await Task.Delay(TimeSpan.FromMinutes(5), stoppingToken); } }
4. 额外优化建议
- 给
when_deleted字段添加数据库索引,提升过滤查询的性能; - 同步时可使用
AddRange等批量操作,减少数据库交互次数; - 加入日志记录,跟踪软删除、新增、更新的用户信息,方便排查问题;
- 测试边界场景:比如用户被删除后又恢复、批量用户被删除等。
内容的提问来源于stack exchange,提问作者Nero Amayo
相关产品推荐
相关产品推荐

