EF Core 8:如何更高效优雅地实现类似SQL Case的查询逻辑?
高效实现EF Core 8中承包商优先级查询的优雅方案
问题背景
需求:优先获取类型为"Prime"的承包商对象,若不存在则获取"Original Prime"类型的对象。
现有实现代码:
var primeCtr = con.Contractors?.Where(ctr => ctr.Type == "Prime").FirstOrDefault(); if (primeCtr == null) primeCtr = con.Contractors?.Where(ctr => ctr.Type == "Original Prime").FirstOrDefault();
尝试过三元表达式,但会导致"Prime"查询执行两次,效率更低:
var primeCtr = con.Contractors?.Where(ctr => ctr.Type == "Prime").Any() ? con.Contractors?.Where(ctr => ctr.Type == "Prime").FirstOrDefault() : con.Contractors?.Where(ctr => ctr.Type == "Original Prime").FirstOrDefault();
作为EF Core 8新手,希望找到更优雅且高效的实现方式。
解决方案
方案1:单次查询结合排序优先级(推荐)
通过OrderByDescending给"Prime"类型设置更高优先级,仅执行一次数据库查询即可满足需求,EF Core会自动生成高效的SQL:
var primeCtr = con.Contractors? .Where(ctr => ctr.Type is "Prime" or "Original Prime") .OrderByDescending(ctr => ctr.Type == "Prime") .FirstOrDefault();
逻辑说明:先筛选出两种类型的承包商,再将"Prime"类型的记录排在最前面,最后取第一条结果。既保证了优先级,又避免了多次数据库请求。
方案2:简化原有逻辑的Nullable合并写法
如果不想提前筛选范围,可以用??合并运算符简化代码,逻辑和原有实现一致,但更紧凑:
var primeCtr = con.Contractors?.FirstOrDefault(ctr => ctr.Type == "Prime") ?? con.Contractors?.FirstOrDefault(ctr => ctr.Type == "Original Prime");
说明:直接用FirstOrDefault带筛选条件替代Where+FirstOrDefault,代码更简洁,同样是先查询"Prime",不存在再查询"Original Prime"。
内容的提问来源于stack exchange,提问作者jrichview
相关产品推荐
相关产品推荐

