如何查询/将数据转换为所需的格式
Posted
技术标签:
【中文标题】如何查询/将数据转换为所需的格式【英文标题】: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
是否可以使用单个投影?分配列表时遇到问题。
另外,我可以学习这种转换的任何链接?例子 到目前为止,我发现它们相当简单或解释不清。
【问题讨论】:
【参考方案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);
【讨论】:
显然示例可以在代码审查之前清理很多,并且应该,但是为了清楚地向某人概述一个解决方案,没有给出更接近的示例,我认为它可以说明解决问题的简化方法,它确实有助于转换 谢谢。正在做类似的事情来实现结果,但通过从数据库中选择来完成分组。我同意可维护的>花哨的代码。以上是关于如何查询/将数据转换为所需的格式的主要内容,如果未能解决你的问题,请参考以下文章