如何查询/将数据转换成所需的格式

How to query / transform the data into the desired format

不知道有没有人能帮我把下面的数据(从数据库)转换成 列表:

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
}

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

另外,有什么链接可以让我学习这种转换吗?例子 到目前为止,我发现它们相当简单或解释不当。

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

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);
}

您可以使用 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};