繁体   English   中英

在linq查询中计算总数

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM