.NET6升级后LINQ Npgsql报Heterogeneous type mappings错误如何解决
问题原因
这个报错是EF Core 6.0引入的破坏性变更导致的,和.NET 6的LINQ转SQL规则调整有关:
- 当插值字符串
$""的拼接项≤3个时,EF Core 6会翻译为对应参数数量的string.Concat重载,不需要创建数组,因此不会触发类型校验问题,这就是你前3个label能正常执行的原因。 - 当拼接项≥4个时,EF Core会将插值语法翻译为接收
params object[]参数的string.Concat重载,需要先把所有拼接项放进同一个数组里。EF Core 6新增了数组元素的类型一致性校验,你的示例中数组同时包含string、decimal、可空string三种不同类型,无法通过类型映射检查,就会抛出Heterogeneous type mappings detected when making new array错误。
而EF Core 5没有这项严格的类型校验,会自动隐式把所有非string类型转换为字符串处理,所以相同代码能正常运行。
解决方案
你可以选择以下任意一种方式修复:
- 显式转换所有非string类型为字符串
给label4里的decimal类型的mRP手动调用ToString(),可空类型可以按需加空值处理,示例:label4 = $"{i.itemDesc} | {ia.addlUoM} | M-{ia.mRP.ToString()} | {b.barCodeOrShortCode ?? string.Empty}" - 内存中完成拼接
先把需要的字段查询到内存后再做字符串拼接,适合数据量不大的场景:var a = (from i in _context.Items join t in _context.ItemAttrs on i.itemCode equals t.itemCode into temp from ia in temp.DefaultIfEmpty() join t1 in _context.BarCodes on ia.id equals t1.itemAttrID into temp1 from b in temp1.DefaultIfEmpty() select new { i.itemDesc, ia.addlUoM, ia.mRP, b.barCodeOrShortCode, // 其他需要的字段 }) .Distinct() .AsEnumerable() // 后续操作在内存执行 .Select(x => new { label = $"{x.itemDesc} | {x.addlUoM} | {x.barCodeOrShortCode}", label2 = $"{x.itemDesc} | {x.addlUoM} | M-{x.mRP.ToString()}", label3 = $"{x.itemDesc} | M-{x.mRP} | {x.barCodeOrShortCode}", label4 = $"{x.itemDesc} | {x.addlUoM} | M-{x.mRP} | {x.barCodeOrShortCode}", // 其他属性 }).ToList(); - 使用EF内置的拼接函数
调用EF.Functions.Concat显式拼接字符串,规避插值的自动翻译问题。
内容的提问来源于stack exchange,提问作者Ramesh
相关产品推荐
相关产品推荐

