【问题标题】:C# Linq select/join with custom return typeC# Linq 选择/加入自定义返回类型
【发布时间】:2020-06-25 15:14:38
【问题描述】:

我有以下 linq 示例:

List<FoodOrderItem> foodOrderItems = foodItemsWithPricesDbResult.ResultValue;

List<FoodOrderItem> orderItemsWithDiscounts= (from orderItem in order.Items
 join foodOrderItem in foodOrderItems
 on orderItem.FoodId equals foodOrderItem.Id
 select mergeOrderAndFoodInformation(foodOrderItem,orderItem)).ToList();

.
.
.
private static FoodOrderItem mergeOrderAndFoodInformation(FoodOrderItem foodOrderItem, OrderItem orderItem)
{
    foodOrderItem.DiscountValue = orderItem.DiscountValue;
    foodOrderItem.DiscountKind = orderItem.DiscountKind;
    foodOrderItem.CurrentOrderedCount = orderItem.Count;
    return foodOrderItem;
}

mergeOrderAndFoodInformation 函数更新输入foodOrderItem 对象的某些字段并返回更新后的foodOrderItem。

1- 如果我不想使用mergeOrderAndFoodInformation 之类的函数来更新和返回结果,如何以inline 样式编写select mergeOrderAndFoodInformation(foodOrderItem,orderItem) 部分?我的意思是,如果我想在不使用外部函数的情况下编写代码,如何更改 select mergeOrderAndFoodInformation(foodOrderItem,orderItem) 段?

2- 如何使用 Lambda 表示法编写此 linq 查询?

附:如果没有正确使用 inlineexternal 等关键字,请接受我的道歉。如有错误,敬请指正。

【问题讨论】:

  • 为什么要内联函数?您是否希望它能够消除您的查询无法转换为 SQL 的错误?
  • @DStanley 我想学习语法,我知道上面的语法更具可读性。 Are you hoping that it will get rid of errors that your query can't be translated to SQL? 是什么意思?能解释一下吗?
  • 如果您没有收到类似的错误,请不要担心。这些问题的出现通常是因为将 linq 查询转换为 SQL 时出错,而内联通常无法修复。

标签: c# linq join lambda


【解决方案1】:

您正在修改源集合中的对象,这在使用 Linq 时通常不是最佳做法。它将要求您使用 lambda 语法来内联函数,如下所示:

order.Items.Join(foodOrderItems, oi=>oi.FoodId, foi=>foi.Id, (oi, foi) => new {oi, foi})
           .Select(j => {
                          j.foi.DiscountValue = j.oi.DiscountValue;
                          j.foi.DiscountKind = j.oi.DiscountKind;
                          j.foi.CurrentOrderedCount = j.oi.Count;   
                          return j.foi;                         
                        })
            .ToList()

请注意,Join 在 lambda 语法中更丑陋(恕我直言),并且内联函数不会给您带来很多好处。

【讨论】:

    【解决方案2】:
        List<FoodOrderItem> foodOrderItems = foodItemsWithPricesDbResult.ResultValue;
    
        List<FoodOrderItem> orderItemsWithDiscounts = (from orderItem in order.Items
                                                   join foodOrderItem in foodOrderItems
                                                   on orderItem.FoodId equals foodOrderItem.Id
                                                   select new FoodOrderItem
                                                   {
                                                       DiscountValue = orderItem.DiscountValue,
                                                       DiscountKind = orderItem.DiscountKind,
                                                       CurrentOrderedCount = orderItem.Count
                                                   }).ToList();
    

    您可以在那里自己创建新对象。

    【讨论】:

    • 这是创建新的FoodOrderItem 对象,而不是更新原始对象的属性。我怀疑原来的 FoodOtherItemother 属性,使用这种方法会丢失。
    • @DStanley 注意到还有一些其他字段会以这种方式丢失,我不想这样写,因为将来通过将每个新字段添加到我的对象中,我需要更新所有逐个传递字段的代码。
    • @VSB 对不起,我想这是不可能的,因为 LINQ 只提供了新的列表来迭代。它不能对现有的做任何事情。
    猜你喜欢
    • 1970-01-01
    • 2011-09-23
    • 2013-03-21
    • 2022-12-06
    • 2014-09-08
    • 1970-01-01
    • 2013-03-04
    • 1970-01-01
    • 2016-10-13
    相关资源
    最近更新 更多