【问题标题】:How to query / transform the data into the desired format如何查询/将数据转换为所需的格式
【发布时间】:2021-12-05 09:26:50
【问题描述】:

我想知道是否有人可以帮助我将以下数据(来自数据库)转换为 列表:

Lorryid productid qtytype Qty iscomment comment
1 4090 3 2 f
1 4153 3 1 f
1 4153 3 1 f
1 4153 3 1 f
1 4153 3 1 f
1 4153 3 1 f
1 31068 3 2 f
1 31069 3 2 f
1 31173 3 2 f
2 17 0 1.000 f
2 150 3 6.000 f
2 216 3 6.000 f
2 278 2 1.020 f
2 398 2 1.125 f
2 398 2 1.090 f
2 398 2 0 t MUST BE RIPE
2 431 2 3.000 f
2 436 3 1.000 f
2 446 0 1 f
2 446 2 3.045 f
2 451 3 2.000 f
2 457 3 1.000 f
2 458 3 4.000 f
2 478 3 1.000 f
2 510 2 1.140 f
2 518 3 3.000 f
2 518 3 4.000 f
2 550 2 1.170 f
2 550 3 1.000 f

进入下面的对象。

public class View
{
  public List<LorryLoading> Report
}

public class LorryLoading
{
  public int LorryId
  public List<Product> Product
}

public class Product
{
  public int ProductId
  public decimal Qty0 sum(Quantity) WHERE QtyType = 0
  public decimal Qty2 sum(Quantity) WHERE QtyType = 2
  public decimal Qty3 sum(Quantity) WHERE QtyType = 3
  public List<string> Comments
}

是否可以使用单个投影?分配列表时遇到问题。

另外,我可以学习这种转换的任何链接?例子 到目前为止,我发现它们相当简单或解释不清。

【问题讨论】:

    标签: c# linq linq-to-sql


    【解决方案1】:

    您可以使用 Linq 的 Aggregate 进行自定义聚合。这稍微复杂一些,因为您在这里进行了双重聚合。

    请注意,这可能仅适用于 Linq-to-Objects。

    var report = data
        .GroupBy(row => row.Lorryid)
        .Select(l => new LorryLoading {
            LorryId = l.Key,
            Product = l
                .GroupBy(row => row.productid)
                .Select(p => p.Aggregate(
                    new Product {ProductId = p.Key},  // this is the starting object
                    (prod, row) => {                  // this aggregates it up
                        if(comment != null)
                            prod.Comments.Add(row.comment);
                        if(QtyType == 0)
                            prod.Qty0 += row.Quantity;
                        else if(QtyType == 2)
                            prod.Qty2 += row.Quantity;
                        else if(QtyType == 3)
                            prod.Qty3 += row.Quantity;
                    })
                .ToList()
         }).ToList();
    
    var view = new View {Report = report};
    

    【讨论】:

      【解决方案2】:

      您要问的是转换,因此没有简单的投影。你可以用一个超级复杂的语句来做到这一点,这会让你的同事在必须维护时换工作:) 我的建议是不要试图给校园留下深刻印象,而是专注于干净的代码:

      var lorryLoadingReport = new List<ReportData>();
      //Presume you already have data into a transport object and know how to read that, as it wasn't your question
      
      var view = new View
      {
          Report = new List<LorryLoading>()
      };
      var listOf = new List<Product>();
              
      //Lets not over complicate our mind, just keep it simple, let's get the products and the lorries
      var productsList = lorryLoadingReport.Select(x => x.ProductId).ToList();
      var lorriesList = lorryLoadingReport.Select(x => x.LorryId).ToList();
      foreach (var lorry in lorriesList)
      {
          //We'll need an entry even if the list will be empty
          var lorryLoading = new LorryLoading
          {
              LorryId = lorry,
              Product = new List<Product>()
          };
      
          //Get the respective subset
          var lorryLoadingReportPerLorry = lorryLoadingReport.Where(l => l.LorryId == lorry);
          if (lorryLoadingReportPerLorry.Any())
          {
              foreach (var productId in productsList)
              {
                  //And add a product with all 4 sums iteratively
                  var p = new Product
                  {
                      ProductId = productId,
                      Comments = new List<string>()
                  };
                  var commentsList = lorryLoadingReport.Where(x => x.ProductId == productId && x.IsComment == "t").Select(s => s.Comment).ToList();
                  if(commentsList.Any())
                      p.Comments.AddRange(commentsList);
                  p.Qty0 = lorryLoadingReport.Where(x => x.Qty == 0).Sum(y => y.Qty);
                  p.Qty2 = lorryLoadingReport.Where(x => x.Qty == 2).Sum(y => y.Qty);
                  p.Qty3 = lorryLoadingReport.Where(x => x.Qty == 3).Sum(y => y.Qty);
      
                  lorryLoading.Product.Add(p);
              }
          }    
          view.Report.Add(lorryLoading);
      }
      

      【讨论】:

      • 显然示例可以在代码审查之前清理很多,并且应该,但是为了清楚地向某人概述一个解决方案,没有给出更接近的示例,我认为它可以说明解决问题的简化方法,它确实有助于转换
      • 谢谢。正在做类似的事情来实现结果,但通过从数据库中选择来完成分组。我同意可维护的>花哨的代码。
      猜你喜欢
      • 2021-04-25
      • 2020-05-11
      • 2019-11-21
      • 2021-01-01
      • 2017-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多