【问题标题】:Left Join in Linq and using the variable for other joins在 Linq 中左连接并将变量用于其他连接
【发布时间】:2011-10-04 09:07:45
【问题描述】:

当我在 Linq 中为 DataSet 使用左联接时,我遇到了错误“值不能为空。参数名称行”。

以下是数据和 linq 查询。

  • DataRowCollection - 项目(列 - Item_id、SKU、数量)
  • DataRowCollection - 促销(列 - Item_id、Promotion_Id)
  • DataRowCollection - 组件(列 - Component_id、Promotion_id)
  • DataRowCollection - 金额(列 - Component_id、Amount_Text、货币)
        var q = 
            from Item in items
            join promotion in promotions
                on Item.Field<int>("Item_id") equals promotion.Field<int?>("Item_id") into promo
            from promotion in promo.DefaultIfEmpty()
            join disccomponent in components
                on promotion.Field<int>("Promotion_Id") equals disccomponent.Field<int?>("Promotion_Id")
            join discamounts in amounts
                on disccomponent.Field<int>("Component_id") equals discamounts.Field<int?>("Component_id")
            where disccomponent.Field<string>("Type") == "Principal"
            select new
            {
                SKU = Item.Field<string>("SKU"),
                Quantity = Item.Field<string>("Quantity"),
                DiscountAmount = discamounts.Field<string>("Amount_Text"),
                DiscountCurrency = discamounts.Field<string>("currency")
            };

我需要得到以下信息:

  • 有折扣的商品的 SKU、数量和折扣详情
  • SKU,无折扣商品的数量

当所有项目都有折扣时,代码在没有左外连接的情况下工作,但如果任何项目没有任何折扣,它会跳过该项目,因此我必须使用左外连接。

非常感谢任何帮助。如果需要任何澄清,请告诉我。

提前致谢。

【问题讨论】:

    标签: c# linq left-join


    【解决方案1】:

    我认为您正在尝试访问 null disamounts 上的属性。也许您选择的新产品应该看起来像这样......

    select new
    {
        SKU = Item.Field<string>("SKU"),
        Quantity = Item.Field<string>("Quantity"),
        DiscountAmount = discamounts == null ? "" : discamounts.Field<string>("Amount_Text"),
        DiscountCurrency = discamounts == null ? "" : discamounts.Field<string>("currency")
    };
    

    【讨论】:

    • 试过这个但还是一样的错误“value cannot be null.parameter name:row”
    【解决方案2】:

    使用into 为您的加入命名,并在其上使用DefaultIfEmpty。像这样(查看语句中的最后一个joinfrom 表达式)

    var q = 
        from Item in items
        join promotion in promotions
            on Item.Field<int>("Item_id") equals promotion.Field<int?>("Item_id") into promo
        from promotion in promo.DefaultIfEmpty()
        join disccomponent in components
            on promotion.Field<int>("Promotion_Id") equals disccomponent.Field<int?>("Promotion_Id")
        join discamounts in amounts
            on disccomponent.Field<int>("Component_id") equals discamounts.Field<int?>("Component_id") into DiscamountJoin
        from discamount in DiscamountJoin.DefaultIfEmpty()
        where disccomponent.Field<string>("Type") == "Principal"
        select new
        {
            SKU = Item.Field<string>("SKU"),
            Quantity = Item.Field<string>("Quantity"),
            DiscountAmount = discamount.Field<string>("Amount_Text"),
            DiscountCurrency = discamount.Field<string>("currency")
        };
    

    【讨论】:

    • 感谢您的输入,但它失败并出现同样的错误。我将其划分为 2 个 linq 查询,它可以工作。将发布解决方案。请检查一下,看看你能不能帮我把它做得更好。
    【解决方案3】:

    感谢大家的帮助。我通过将其拆分为下面的 2 个不同的 linq 查询来完成这项工作。

    第一个查询在 var 中获取促销数据

            var promoData =
                    from promotion in promotions
                    join component in components
                        on promotion.Field<int>("Promotion_Id") equals component.Field<int?>("Promotion_Id")
                    join amount in amounts
                        on component.Field<int>("Component_id") equals amount.Field<int?>("Component_id")
                    where component.Field<string>("Type") == "Principal"
                    select new
                    {
                        Item_id = promotion.Field<int?>("Item_id"),
                        Promotion_id = promotion.Field<int>("Promotion_Id"),
                        DiscountAmount = amount == null ? "" : amount.Field<string>("Amount_Text"),
                        DiscountCurrency = amount == null ? "" : amount.Field<string>("currency")
                    };
    

    第二个查询使用promotions var来简化查询并获得结果

            var q = 
                from Item in items
                join promotion in promoData
                    on Item.Field<int>("Item_id") equals promotion.Item_id into promo
                    from promoJoin in promo.DefaultIfEmpty()
                select new
                {
                    SKU = Item.Field<string>("SKU"),
                    Quantity = Item.Field<string>("Quantity"),
                    DiscountAmount = promoJoin != null ? promoJoin.DiscountAmount : "0",
                    DiscountCurrency = promoJoin != null ? promoJoin.DiscountCurrency : ""
                };
    

    这种方法非常有效,无论是否有促销活动,我都能获得所有商品。我仍在考虑是否可以在单个查询中执行相同的操作:) 现在将其标记为答案,如果有人想出其他更好的方法来标记它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-20
      • 1970-01-01
      • 2010-10-06
      • 1970-01-01
      • 1970-01-01
      • 2016-10-25
      • 1970-01-01
      相关资源
      最近更新 更多