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

EF Core 7 ExecuteDeleteAsync在内存数据库中执行报错问题

EF Core 7 ExecuteDeleteAsync()内存数据库测试失败问题

问题情况

EF Core 7新增的ExecuteDeleteAsync()功能在真实MsSql Server中可正常运行,但使用最新版Microsoft.EntityFrameworkCore.InMemory内存数据库编写测试用例时执行失败,推测是该特性的无追踪批量操作机制导致内存数据库不支持。

相关代码

删除方法

public async Task<int> DeleteWhere(Expression<Func<T, bool>> predicate)
{
  var amount = await _dbSet.Where(predicate).ExecuteDeleteAsync();
  return amount;
}

数据库上下文创建代码

public DashboardDbContext CreateDashboardContext()
{
    var dbName = $"xUnitTest{_instanceCount++}";
    var builder = new DbContextOptionsBuilder<DashboardDbContext>();

    builder.UseInMemoryDatabase(dbName);

    return new DashboardDbContext(builder.Options);
}

抛出的异常信息(中文翻译)

{"LINQ表达式'DbSet()\r\n.Where(b => b.ModifiedTime < __dateToKeepData_0)\r\n .ExecuteDelete()'无法被转换。请将查询重写为可转换的形式,或者通过插入对'AsEnumerable'、'AsAsyncEnumerable'、'ToList'或'ToListAsync'的调用显式切换到客户端评估。"}

原因与解决方案

原因确认

你的推测完全正确:EF Core 7的ExecuteUpdate/ExecuteDelete属于无追踪批量操作,这类操作直接基于LINQ生成数据库层面的删除/更新语句,跳过EF的变更追踪系统。而InMemory内存数据库提供程序不支持这类批量操作的SQL翻译逻辑,仅能处理依赖变更追踪的常规CRUD操作。

解决方案

  1. 测试场景适配方案:改用客户端评估模拟批量删除(会先加载数据到内存再删除,和真实数据库批量操作行为有差异,仅适合测试):
    public async Task<int> DeleteWhere(Expression<Func<T, bool>> predicate)
    {
        var entities = await _dbSet.Where(predicate).ToListAsync();
        _dbSet.RemoveRange(entities);
        await _dbContext.SaveChangesAsync();
        return entities.Count;
    }
    
  2. 贴近真实环境测试方案:替换InMemory为SQLite内存数据库,SQLite支持EF Core批量操作的翻译逻辑,能更准确模拟真实数据库的行为。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 17:42:33