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

.NET Core EF Core单元测试:SQLite不支持APPLY操作致测试失败

问题原因

EF Core针对SQL Server和SQLite的查询翻译逻辑存在差异:当你在嵌套的Produits集合投影后使用Distinct()时,EF Core会为SQL Server生成依赖APPLY操作的SQL语句,但SQLite并不支持APPLY语法,因此单元测试抛出异常。移除Distinct()后,查询无需APPLY操作,SQLite可以正常解析执行。

解决方案

方案1:将去重逻辑移到客户端执行

先从数据库拉取完整数据到内存,再在客户端对集合做去重处理,避免EF Core生成SQLite不支持的语句:

// 提前Include关联的Produits,避免后续N+1查询
var commandes = await _context.Commandes
    .Where(c => c.Numero == numero)
    .Include(c => c.Produits)
    .ToListAsync(cancellationToken);

var result = commandes.Select(command => new CommandeDto
{
    Numero = command.Numero,
    Produits = command.Produits
        .Select(s => new ProduittDto
        {
            Id = s.Id, // 原代码中`s.s.Id`应为笔误,修正为`s.Id`
            Libelle = s.Name
        })
        .Distinct()
        .ToList()
}).ToList();

注意:如果ProduittDto没有重写Equals和GetHashCode,Distinct()可能无法按预期去重,需要为该DTO实现相等性判断逻辑,或者改用.NET 6+支持的DistinctBy:

.Produits
.Select(s => new ProduittDto { Id = s.Id, Libelle = s.Name })
.DistinctBy(dto => new { dto.Id, dto.Libelle })
.ToList()

方案2:用GroupBy替代Distinct实现去重

通过GroupBy按去重字段分组,再从分组中取数据,EF Core可以将这种逻辑转换成SQLite支持的语句:

var result = await (from command in _context.Commandes
                    where command.Numero == numero
                    select new CommandeDto
                    {
                        Numero = command.Numero,
                        Produits = command.Produits
                            .GroupBy(s => new { s.Id, s.Name })
                            .Select(g => new ProduittDto
                            {
                                Id = g.Key.Id,
                                Libelle = g.Key.Name
                            })
                            .ToList()
                    }).ToListAsync(cancellationToken);

方案3:统一单元测试与生产环境数据库

如果希望保持查询逻辑不变,可以改用支持APPLY操作的数据库做单元测试,比如SQL Server LocalDB或Docker化的SQL Server实例,这样查询在测试和生产环境的行为完全一致,避免数据库兼容性问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 08:59:15