如何简化这段获取粮食订单的LINQ查询代码?
LINQ查询简化方案
你原代码里的重复判断主要是两次硬编码了i.Sku.Contains("GRNS")逻辑,而且多了一行无意义的Select(o => o),可以按照你是否允许修改原始Order对象选择两种优化方案:
方案1:投影新Order对象(无副作用,推荐)
这种方案不会修改GetOrdersJson()返回的原始订单对象,符合LINQ函数式编程的设计习惯:
public List<Order> GetGrainOrders() { // 统一抽离粮食SKU的判断逻辑,后续修改规则只需调整这里 Func<LineItem, bool> IsGrainSku = item => item.Sku.Contains("GRNS"); return GetOrdersJson() .Select(originOrder => new Order { // 此处补充赋值Order需要保留的所有原有属性,示例如下 Id = originOrder.Id, OrderNumber = originOrder.OrderNumber, CreateTime = originOrder.CreateTime, // 直接过滤出符合要求的行项,无需后续删除操作 LineItems = originOrder.LineItems.Where(IsGrainSku).ToList() }) // 过滤掉没有粮食行项的空订单 .Where(order => order.LineItems.Any()) .ToList(); }
方案2:修改原有Order对象(适配必须改原对象的场景)
如果业务要求必须修改原始Order实例,可简化为以下写法:
public List<Order> GetGrainOrders() { Func<LineItem, bool> IsGrainSku = item => item.Sku.Contains("GRNS"); var orders = GetOrdersJson().ToList(); // 先移除所有不含粮食行项的订单 orders.RemoveAll(order => !order.LineItems.Any(IsGrainSku)); // 再移除每个订单里的非粮食行项 orders.ForEach(order => order.LineItems.RemoveAll(item => !IsGrainSku(item))); return orders; }
核心优化点
- 抽离重复的SKU判断逻辑为独立委托,避免重复硬编码,后续维护只需修改一处
- 移除原代码中无实际作用的
Select(o => o)冗余调用 - 方案1避免了对原始数据的修改,降低了业务侧意外污染原始订单数据的风险
内容的提问来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

