[英]C# SQL/Linq/Entity Framework calculating column totals for multiple columns from large data source
[英]Calculating totals in linq query
我有一个名为JobReport的模型,看起来像这样(简化)
public class JobReport
{
public JobReport()
{
WorkOrders = new List<WorkOrder>();
}
public int JobID { get; set; }
public decimal WorkOrderTotal {get; set; }
public List<WorkOrder> WorkOrders{ get; set; }
}
public class WorkOrder
{
public WorkOrder()
{
Total = 0;
}
public string Trade { get; set; }
public int WorkOrderID { get; set; }
public decimal? Total { get; set; }
}
现在,我有了一个Linq查询,这要感谢所有具有WorkOrders且其交易在传递数组中的工作的Job,这要归功于Linq Query,其中相关实体包含array的值 :
jobs = jobs
.Where(x => x.WorkOrders.Any(y => trades.Contains(y.Trade)));
现在如何获取WorkOrderTotal,即满足上述查询谓词的工单中的Total的总和? 我看不到如何在任何地方添加.Sum()?
编辑
只是为了确认,每个工作都需要给定行业中工作单的总和。
尝试这样的事情:
IEnumerable<decimal> workOrderTotals = jobs
.Where(x => x.WorkOrders.Any(y => trades.Contains(y.Trade)))
.Select( j => j.WorkOrders.Sum(wo => wo.Total ?? 0));
这是一个测试用例:
var jobs = new List<JobReport>();
jobs.Add(new JobReport{ WorkOrders = new List<WorkOrder>{ new WorkOrder{ Total = 10} }});
jobs.Add(new JobReport { WorkOrders = new List<WorkOrder> { new WorkOrder { Total = 10 }, new WorkOrder { Total = 10 } } });
结果是包含2个值10,20的可枚举
将此视为测试数据
JobReport job1 = new JobReport();
job1.JobID = 1;
job1.WorkOrders.Add(new WorkOrder() { WorkOrderID = 2, Trade = "trade1", Total = 10});
job1.WorkOrders.Add(new WorkOrder() { WorkOrderID = 3, Trade = "trade2", Total = 20 });
job1.WorkOrders.Add(new WorkOrder() { WorkOrderID = 4, Trade = "trade1", Total = 25 });
JobReport job2 = new JobReport();
job2.JobID = 2;
job2.WorkOrders.Add(new WorkOrder() { WorkOrderID = 1, Trade = "trade1", Total = 10 });
job2.WorkOrders.Add(new WorkOrder() { WorkOrderID = 5, Trade = "trade2", Total = 20 });
job2.WorkOrders.Add(new WorkOrder() { WorkOrderID = 6, Trade = "trade2", Total = 30 });
job2.WorkOrders.Add(new WorkOrder() { WorkOrderID = 7, Trade = "trade3", Total = 10 });
List<JobReport> jobs = new List<JobReport>();
jobs.Add(job1);
jobs.Add(job2);
你可以做这样的事情。
var groupedJobs = jobs.GroupBy(a => a.JobID)
.Select(b => new { JobId = b.Key, WorkOrdersByTrade = b.Select(c => c.WorkOrders.GroupBy(d => d.Trade)
.Select(g => new { Trade = g.Key, tradeSum = g.Sum(s => s.Total) })) });
通过定义以下类进一步
public class TradeTotal
{
public string Trade { get; set; }
public decimal? Total { get; set; }
}
public class JobTrade
{
public int JobId { get; set; }
public List<TradeTotal> TradeTotals { get; set; }
}
您可以以所需的格式获得结果
var JobTradeList = groupedJobs.Select(x => new JobTrade() { JobId = x.JobId, TradeTotals = x.WorkOrdersByTrade.SelectMany(s => s.Select(v => new TradeTotal() { Total = v.tradeSum, Trade = v.Trade })).ToList() }).ToList();
代码可能不是100%干净的; 但是我想这就是你所追求的。
对于已经发布的解决方案,也许稍微容易一点的解决方案是在JobReport中添加一个名为WorkOrderValue的属性:
public decimal? WorkOrdersValue { get; set; }
现在,您可以查询符合条件的职位:
jobs = jobs
.Where(x => x.WorkOrders
.Any(y => trades.Contains(y.Trade.ToLower())))
.ToList();
并分别计算每个作业的总数:
foreach (var job in jobs)
{
job.WorkOrdersValue = job.WorkOrders.Where
(y => trades.Contains(y.Trade.ToLower())).Sum(wo => wo.Total);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.