在c#

时间:2017-06-20 22:50:22

标签: c# linq

public class APIBillingHistory
{        
    public List<APIBillingHistoryDetails> BillingHistoryDetails;
}

public class APIBillingHistoryDetails
{   
    public List<APIBillingHistoryPaymentType> PaymentType;
    public string BillId;
}

public class APIBillingHistoryPaymentType
{
    public string Description;
    public Decimal Principal;
}

我有一类嵌套列表对象。我想将各个PaymentList集合合并到其父列表APIBillingHistoryDetails

例如:

APIBillingHistory
-----BillingHistoryDetails
        Bill ID : 123
        ----PaymentType
                Description : "A"
                Principal : 100
        ----PaymentType
                Description : "B"
                Principal : 200
-----BillingHistoryDetails
        Bill ID : 123
        ----PaymentType
                Description : "A"
                Principal : 150
        ----PaymentType
                Description : "B"
                Principal : 300

我们说我有上面指定的样本日期。我想产生以下格式。在合并 PaymentList 添加 Principal属性每个 Description值,如果他们有< strong>相同的帐单ID

输出应如下所示:

APIBillingHistory
-----BillingHistoryDetails
        Bill ID : 123
        ----PaymentType
                Description : "A"
                Principal : 250
        ----PaymentType
                Description : "B"
                Principal : 500

3 个答案:

答案 0 :(得分:3)

这将提供所需的输出

var merged = new APIBillingHistory {
    BillingHistoryDetails = history
        .BillingHistoryDetails
        .GroupBy(detail => detail.BillId) //Group same bill Ids
        .Select(detailGroup => new APIBillingHistoryDetails {
            BillId = detailGroup.Key,
            PaymentType = detailGroup.SelectMany(p => p.PaymentType) //Get all payments
                .GroupBy(pymtType => pymtType.Description) //and group them by description
                .Select(pymtTypeGroup => new APIBillingHistoryPaymentType { //construct payment type
                    Description = pymtTypeGroup.Key,
                    Principal = pymtTypeGroup.Sum(t => t.Principal) // summing all grouped principals
                }).ToList()
        }).ToList()
};

鉴于

var history = new APIBillingHistory {
    BillingHistoryDetails = new List<APIBillingHistoryDetails> {
         new APIBillingHistoryDetails {
              BillId = "123",
              PaymentType = new List<APIBillingHistoryPaymentType>{
                  new APIBillingHistoryPaymentType {
                     Description = "A",
                     Principal = 100
                  },
                  new APIBillingHistoryPaymentType {
                     Description = "B",
                     Principal = 200
                  }
              }
         },
         new APIBillingHistoryDetails {
              BillId = "123",
              PaymentType=new List<APIBillingHistoryPaymentType>{
                  new APIBillingHistoryPaymentType {
                     Description = "A",
                     Principal = 150
                  },
                  new APIBillingHistoryPaymentType {
                     Description = "B",
                     Principal = 300
                  }
              }
         }
     }
};

答案 1 :(得分:2)

我知道这很丑,但至少它有效:)

List<APIBillingHistoryDetails> newList = (from item in BillingHistoryDetails.GroupBy(t => t.BillId)
    let paymentType = item
        .SelectMany(t => t.PaymentType)
        .GroupBy(t => t.Description)
        .Select(t => new APIBillingHistoryPaymentType
        {
            Description = t.Key.Description,
            Principal = t.Sum(s => s.Principal)
        })
        .ToList()
    select new APIBillingHistoryDetails
    { 
        BillId = item.Key,
        PaymelntType = paymentType
    }
).ToList();

答案 2 :(得分:0)

所以你有一个ApiBillingHistory,它有一个或多个ApiBillingHistoryDe​​tails,而且每个APIBillingHistoryDe​​tail都有零个或多个APIBillingHistoryPaymentTypes。

并且您希望将具有相同Id的所有ApiBillingHistoryDe​​tails组合到一个ApiBillingHistoryDe​​tail中,其中PaymentTypes是具有相同描述的所有ApiBillingHistoryPaymentTypes的组以及组中元素的所有Principal值的总和。

如果一个ApiBillingHistoryDe​​tail包含不属于任何其他ApiBillingHistoryDe​​tail的Id,则您没有提及您想要的内容。如果一个PayMentType描述不在其他paymentTypes中,也不会。

 // take all BillingHistoryDetails
var groups = ApiBillingHistory.BillingHistoryDetails
    // group them into groups of items with the same Id
   .GroupBy(
        // Key of the group is this same Id
        historyDetail => historyDetail.Id,
        // elements of the group:
        // group all payment types of the history detail
        // into subgroups of items with the same Description
        historyDetail => historyDetail.PaymentTypes.GroupBy( 
                // Key of subgroup: the Description                                  
                paymentType => payMentType.Description,
                // elements of the gorup = the Principal
                // of the paymentTypes with this description
                paymentType => paymentType.Principal), 

             // now we have sub groups of Principals from all paymentTypes
             // with a Description equal to the sub group.
             // convert every sub Group into one PaymentType:
             .Select(subGroup => new PaymentType()
             {
                 Description = subGroup.Key,
                 Principal = subGroup.Sum(),
             }))

       // so now we have Groups
       // with a Key historyDetail.Id
       // and as elements the list of PaymentTypes
       // where each payMentType contains the Description and the sum of all
       // payment types with this description
       // convert to billingHistoryDetails:
       .Select(mainGroup => new BillingHistoryDetails
       {
          // Id is the Key of the group
          Id = mainGroup.Key,
          // PaymentType is the list of created PaymentTypes
          PaymentType = mainGroup.ToList(),
       });