EF Core拼接不同Varchar长度实体模型的LINQ查询问题
解决EF Core拼接不同长度字符串字段的Concat失效问题
问题根源
SQL Server对CONCAT操作的参与字段有类型兼容要求,前两张表的Thing是varchar(256),第三张表是varchar(20),长度不匹配导致EF Core生成的SQL执行失败。
可行解决方案
1. 显式转换字段长度(推荐)
在查询时将第三张表的Thing转换为与前两张一致的长度,EF Core会自动生成对应的SQL转换逻辑:
ThingList = await ctx.Table1.Select(t1 => t1.Thing) .Concat(ctx.Table2.Select(t2 => t2.Thing)) .Concat(ctx.Table3.Select(t3 => EF.Functions.AsVarchar(t3.Thing, 256))) .Distinct().ToListAsync();
也可以用Convert.ToString实现类似效果:
ThingList = await ctx.Table1.Select(t1 => t1.Thing) .Concat(ctx.Table2.Select(t2 => t2.Thing)) .Concat(ctx.Table3.Select(t3 => Convert.ToString(t3.Thing))) .Distinct().ToListAsync();
2. 统一实体与数据库字段长度
如果业务允许,将第三张表的Thing字段在数据库中改为varchar(256),同时更新实体类的标注:
[StringLength(256)] public string Thing { get; set; }
之后生成数据库迁移并执行更新,三个字段长度统一后拼接查询即可正常运行。
3. 内存中拼接(适合小数据量)
先将三个表的数据分别查询到内存,再在内存中完成拼接和去重,避开数据库层面的类型限制:
var table1Things = await ctx.Table1.Select(t => t.Thing).ToListAsync(); var table2Things = await ctx.Table2.Select(t => t.Thing).ToListAsync(); var table3Things = await ctx.Table3.Select(t => t.Thing).ToListAsync(); ThingList = table1Things.Concat(table2Things).Concat(table3Things).Distinct().ToList();
内容的提问来源于stack exchange,提问作者BlueCardinal
相关产品推荐
相关产品推荐

