如何简化该LINQ WHERE查询?实现本地化字符串优先级匹配
实现优先匹配多语言的单LINQ查询
可以通过排序优先级+去重的技巧把这三个查询合并成一个,既减少数据库查询次数,又满足你的优先匹配逻辑。
核心思路:
- 先筛选出符合命名空间条件的所有记录,同时给不同语言设置优先级分数:指定language得3分,DevLanguage得2分,FallbackLanguage得1分
- 按优先级降序排序,再根据字符串唯一标识(比如
Key字段,需替换为你实际用的区分字段)去重,保留优先级最高的条目 - 最终提取目标结果
完整实现代码
var localizationStrings = _presentationContext.LocalizationStrings .Where(x => x.Namespace.Namespace == @namespace) .Select(x => new { LocalizationString = x, Priority = x.Namespace.Language == language ? 3 : x.Namespace.Language == Constants.DevLanguage ? 2 : x.Namespace.Language == Constants.FallbackLanguage ? 1 : 0 }) .Where(x => x.Priority > 0) // 过滤掉不属于三种目标语言的记录 .OrderByDescending(x => x.Priority) .GroupBy(x => x.LocalizationString.Key) // 替换为你实际的字符串唯一标识字段 .Select(g => g.First().LocalizationString) .ToList();
简化版(无重复场景)
如果你的数据中,同一命名空间下不会出现同标识的多语言重复记录,可以直接利用布尔值排序特性简化:
var localizationStrings = _presentationContext.LocalizationStrings .Where(x => x.Namespace.Namespace == @namespace) .OrderByDescending(x => x.Namespace.Language == language) .ThenByDescending(x => x.Namespace.Language == Constants.DevLanguage) .ThenByDescending(x => x.Namespace.Language == Constants.FallbackLanguage) .ToList();
注:布尔值排序时true会排在false之前,因此会优先返回指定language的结果,依次 fallback 到DevLanguage和FallbackLanguage。
这种合并写法只会触发一次数据库查询,比原写法的多次Any()查询(最多4次)效率更高。
内容的提问来源于stack exchange,提问作者papetrov
相关产品推荐
相关产品推荐

