基于Collection属性的Item多规则排序实现方案咨询
问题描述
我有两个关联表Collection和Item,实体类定义如下:
Collection 实体
class Collection { int Id; string Title; bool Override; int Level; DateTime Till; int OtherProp; virtual ICollection<Item> Items { get; set; } }
Item 实体
class Item { int Id; int OrderId; string Title; virtual Collection Collection { get; set; } }
需要查询符合条件的Item并按以下优先级排序:
- 所属
Collection的Override为true的Item(优先级最高) - 所属
Collection的Level等于1且Till小于当前时间的Item - 所属
Collection的Level等于2且Till小于当前时间的Item - 其余所有Item(优先级最低)
现有查询框架,需填充OrderBy逻辑:
var resultList = await _context.Items.Where(item=> item.OtherProp == 1) .OrderBy(item => ??????????????) .ThenBy(item=> item.Title).ToListAsync();
解决方案
可以通过为不同优先级的条件分配排序权重值的方式实现,EF Core会将该逻辑转换为SQL中的排序条件。具体代码如下:
var currentTime = DateTime.Now; var resultList = await _context.Items .Where(item => item.OtherProp == 1) // 按优先级分配排序键值,值越小排序越靠前 .OrderBy(item => item.Collection.Override ? 0 : item.Collection.Level == 1 && item.Collection.Till < currentTime ? 1 : item.Collection.Level == 2 && item.Collection.Till < currentTime ? 2 : 3) .ThenBy(item => item.Title) .ToListAsync();
逻辑说明
- 最高优先级的条件(
Override == true)分配权重0,排序时排在最前面 - 第二个优先级条件分配权重
1,排在权重0的结果之后 - 第三个优先级条件分配权重
2,排在权重1的结果之后 - 剩余所有情况分配权重
3,排在最后 - 最后通过
ThenBy(item => item.Title)对同一优先级的Item按标题升序排序
注意:如果Collection和Item采用延迟加载,建议提前使用Include加载关联数据,避免N+1查询问题,优化后的代码如下:
var currentTime = DateTime.Now; var resultList = await _context.Items .Include(item => item.Collection) // 提前加载关联的Collection数据 .Where(item => item.OtherProp == 1) .OrderBy(item => item.Collection.Override ? 0 : item.Collection.Level == 1 && item.Collection.Till < currentTime ? 1 : item.Collection.Level == 2 && item.Collection.Till < currentTime ? 2 : 3) .ThenBy(item => item.Title) .ToListAsync();
内容的提问来源于stack exchange,提问作者SpoksST
相关产品推荐
相关产品推荐

