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

EF Core使用List替代DbSet定义ToInMemoryQuery报错如何解决

解决EF Core ToInMemoryQuery无法使用List作为数据源的问题

问题复现

在EF Core中,常规为无键实体配置内存查询的写法基于DbSet作为数据源,示例如下:

modelBuilder.Entity<UrlResource>()
    .ToInMemoryQuery(() => context.Blogs.Select(b => new UrlResource { Url = b.Url }));

单元测试场景下,若尝试直接使用List作为查询源,两种常见写法都会抛出异常:

  • 第一种写法:先将List转为IQueryable再传入
    var urlResources = new List<UrlResource>() { ... }.AsQueryable();
    
    modelBuilder.Entity<UrlResource>()
        .ToInMemoryQuery(() => urlResources);
    
    抛出异常:The LINQ expression could not be translated.
  • 第二种写法:在Lambda内调用AsQueryable
    var urlResources = new List<UrlResource>() { ... };
    
    modelBuilder.Entity<UrlResource>()
        .ToInMemoryQuery(() => urlResources.AsQueryable());
    
    抛出参数类型不匹配的ArgumentException:

    System.ArgumentException : Expression of type 'System.Collections.Generic.List1[UrlResource]' cannot be used for parameter of type 'System.Linq.IQueryable1[UrlResource]' of method 'System.Linq.IQueryable1[UrlResource] Where[UrlResource](System.Linq.IQueryable1[UrlResource], System.Linq.Expressions.Expression1[System.Func2[UrlResource,System.Boolean]])' (Parameter 'arg0')

报错原因

ToInMemoryQuery 传入的Lambda表达式会被EF Core查询翻译器解析,直接捕获外部List/IQueryable变量时,翻译器会将其识别为闭包引用的未知常量,无法识别为可遍历的内存查询源,最终在翻译或执行阶段抛出异常。

可行解决方法

根据使用的EF Core版本和场景,可选择以下方案:

  • 直接在Lambda内初始化集合(兼容所有EF Core版本)
    不要捕获外部变量,直接在查询表达式内初始化List并转为IQueryable,EF Core可以正常解析这类固定值的集合初始化逻辑:
    modelBuilder.Entity<UrlResource>()
        .ToInMemoryQuery(() => new List<UrlResource>
        {
            // 填充测试数据
            new UrlResource { Url = "https://example.com" }
        }.AsQueryable());
    
  • 用EF.Constant包装外部集合(EF Core 5.0+可用)
    如果需要动态传入外部定义的List,使用EF.Constant将集合标记为EF Core可识别的常量节点,避免翻译错误:
    var urlResources = new List<UrlResource>()
    {
        // 提前初始化好测试数据
    };
    
    modelBuilder.Entity<UrlResource>()
        .ToInMemoryQuery(() => EF.Constant(urlResources).AsQueryable());
    
  • 单元测试场景优先用内存数据库填充数据
    如果是单元测试场景,更推荐直接使用EF Core官方的InMemory内存数据库,在测试执行时直接往对应DbSet添加测试数据、调用SaveChanges即可,不需要额外配置ToInMemoryQuery,模拟的运行逻辑和生产环境更接近。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 03:06:16