使用EF LINQ的Contains子句时出现IN操作排序规则不匹配错误如何解决
问题原因
Illegal mix of collations for operation ' IN '错误本质是MySQL执行IN比对时,city表Name字段的排序规则(collation)和C#传入的cityNames列表中字符串的排序规则不一致,导致数据库无法直接执行比对操作。
解决方案
方案1:Linq查询中显式指定排序规则(临时修复,适配单次查询)
直接在查询条件中通过EF.Functions.Collate方法给字段指定和参数一致的排序规则,示例修改后的代码如下:
public List<KeyValuePair<string, int>> GetCityKeyValuesByNames(List<string> cityNames) { // 注意此处排序规则要和你数据库字段实际使用的保持一致,常用为utf8mb4_general_ci/utf8mb4_bin var cityList = _cityRepo .GetConditionalQuery(x => cityNames.Contains(EF.Functions.Collate(x.Name, "utf8mb4_general_ci"))) .Select(x => new { Key = x.Name, Value = x.Id }) .AsEnumerable() .Select(x => new KeyValuePair<string, int>(x.Key, x.Value)) .ToList(); return cityList; }
如果是参数侧排序规则不匹配,也可以反过来给参数加转换,大部分场景下给字段指定和参数一致的规则即可生效。
方案2:实体模型配置固定排序规则(全局生效,推荐)
在EF上下文的实体映射配置中,直接给Name字段指定固定排序规则,后续所有涉及该字段的查询都会自动适配,无需每次查询写转换逻辑:
// 城市实体的Fluent API配置 modelBuilder.Entity<City>() .Property(c => c.Name) .UseCollation("utf8mb4_general_ci"); // 替换为你实际需要的排序规则
同时可以在数据库连接字符串中显式指定字符集,确保传入参数的排序规则统一:server=xxx;database=xxx;user=xxx;password=xxx;CharSet=utf8mb4;
方案3:直接修改数据库字段排序规则
如果不想修改代码,可以直接调整city表Name字段的排序规则,和程序传入参数的排序规则对齐,SQL示例:
ALTER TABLE city MODIFY COLUMN name VARCHAR(255) COLLATE utf8mb4_general_ci NOT NULL;
注意替换上述所有示例中的排序规则为你业务实际需要的版本,区分大小写的场景可使用
utf8mb4_bin,不区分大小写用utf8mb4_general_ci即可。
内容的提问来源于stack exchange,提问作者Vijay Kumbhoje
相关产品推荐
相关产品推荐

