.NET5中EF Core Union不同实体的同ViewModel查询时类型不匹配如何解决
解决方案
针对EF Core 5.0.10执行Union操作时出现的字符串存储类型不匹配问题,可参考以下几种方案解决:
方案1:显式指定常量的非Unicode类型(推荐)
你出现报错的核心原因是EF Core默认将C#字符串常量推断为SQL Server的nvarchar(Unicode)类型,而somefield2是varchar(非Unicode)类型,两边类型不匹配。可以用EF.Functions.AsNonUnicode方法标记常量为非Unicode类型,和数据库字段类型对齐:
var query2 = from a in EntityB select new MyViewModel { field1 = a.somefield3, field2 = EF.Functions.AsNonUnicode("String Constant") };
修改完成后再执行Union操作即可正常生成SQL。
方案2:显式指定字段的存储类型
如果需要严格匹配字段长度,可以用EF.Property方法显式指定常量的存储类型和长度:
var query2 = from a in EntityB select new MyViewModel { field1 = a.somefield3, field2 = EF.Property<string>("String Constant", "varchar(100)") };
方案3:统一对两边字段做类型转换
给两个查询的对应字段都加上统一的显式转换,让EF Core推断出一致的存储类型:
// 统一用Convert.ToString包裹两边的field2字段 var query1 = from a in EntityA select new MyViewModel { field1 = a.somefield1, field2 = Convert.ToString(a.somefield2) }; var query2 = from a in EntityB select new MyViewModel { field1 = a.somefield3, field2 = Convert.ToString("String Constant") };
方案4:内存中执行Union(仅适合小数据量场景)
如果查询返回的数据量不大,可以先把两个查询的结果加载到内存中再执行Union操作,绕开EF Core的SQL翻译限制:
// 先执行SQL查询加载数据到内存 var list1 = query1.ToList(); var list2 = query2.ToList(); // 内存中执行Union var result = list1.Union(list2);
注意:该方案会将全量数据加载到内存,大数据量场景下会出现性能问题,不推荐使用。
内容的提问来源于stack exchange,提问作者Bob5421
相关产品推荐
相关产品推荐

