【问题标题】:LINQ select multiple columns as separate arrayLINQ 选择多列作为单独的数组
【发布时间】:2013-04-25 19:41:27
【问题描述】:

我有表 4 列。

JobId    StateId    Salary       Expense
1           1        35,000      31,000
1           1        33,000      25,000
1           2        28,000      26,000
2           2         7,000      16,000
2           2         6,000      20,000
2           1         9,000      22,000
2           1        15,000      29,000

通过在 C# 中使用 LINQ,我想按 JobId 和 StateId 组合进行分组。对于每个组合,我想要一个 Salary 数组和 Expense 数组。

对于每个组合,我可以将一列作为一个数组,通过使用这个

(from r in myTable.AsEnumerable()
       group r by new {
            jobId = r.Field<int>("JobId"),
            stateId = r.Field<int>("StateId")
        }).ToDictionary(
        l => Tuple.Create(l.Key.jobId, l.Key.stateId),
        l=> (from i in l select i.Field<double>("Salary")).AsEnumerable()
  );

如何在每个组的两个数组中设置 Salary 和 Expense??

我的目标是找到每个组合的平均工资和平均费用,并进行一些其他操作。或者至少告诉我如何选择多个列作为单独的数组。

注意:我不想为每个组合收集匿名对象。

【问题讨论】:

    标签: c# visual-studio-2010 performance linq linq-to-sql


    【解决方案1】:

    要在查询中选择两个不同的列作为集合,您可以这样做:

    var result = 
        (from r in myTable.AsEnumerable()
         group r by new 
         {
             jobId = r.Field<int>("JobId"),
             stateId = r.Field<int>("StateId")
         } into g
         select new 
         {
             g.Key,
             Salaries = g.Select(x => x.Field<double>("Salary")),
             Expenses = g.Select(x => x.Field<double>("Expense"))
         })
        .ToDictionary(
            l => Tuple.Create(l.Key.jobId, l.Key.stateId),
            l => new { l.Salaries, l.Expenses }
        );
    

    然后您可以相当容易地计算平均值:

    var averageSalary = result[...].Salaries.Average();
    var averageExpense = result[...].Expenses.Average();
    

    但是,如果您真正需要的只是平均值,这将起作用:

    var result = 
        (from r in myTable.AsEnumerable()
         group r by new 
         {
             jobId = r.Field<int>("JobId"),
             stateId = r.Field<int>("StateId")
         } into g
         select new 
         {
             g.Key,
             AverageSalary = g.Average(x => x.Field<double>("Salary")),
             AverageExpense = g.Average(x => x.Field<double>("Expense"))
         })
        .ToDictionary(
            l => Tuple.Create(l.Key.jobId, l.Key.stateId),
            l => new { l.AverageSalary, l.AverageExpense }
        );
    

    【讨论】:

    • 感谢您的回答。除了平均水平,我还需要做一些额外的工作。在后面的过程中,我想为特定组合选择费用/工资数组并进行一些处理
    • @KhanSharp 在这种情况下,您可以使用我的第一个代码示例。为了完整起见,我提供了更多信息。
    【解决方案2】:

    不要将 LINQ 用于此类语句。如果您需要计算分组并计算某种平均工资/费用,您可以尝试一个列表:

    List<myType> myList = new List<myType>();
    
    //add stuff to myList
    
    List<myType> JobID1 = new List<myType();
    List<myType> JobID2 = new List<myType();
    
    foreach(var item in myList)
    {
        if(item.JobID == 1)
            JobID1.add(item);
        if(item.JobID == 2)
            JobID2.add(item);
    }
    
    int avgSalOne;
    
    foreach(var item in JobID1)
    {
        avgSalOne += item.Salary;
    }
    
    avgSalOne = avgSaleOne / JobID2.Count;
    
    //Note that you get Job Id 2 average salary the same way, and also the Expense by changing item. Salary to item.Expense
    

    【讨论】:

    • 如果他开始组合JobIDStateID,将会有很多IF statements
    • 我有一个非常大的数组,我想利用延迟执行 LINQ 以及并行执行
    • @KhanSharp 你不会在这里并行执行
    猜你喜欢
    • 2015-07-04
    • 2011-06-19
    • 1970-01-01
    • 1970-01-01
    • 2011-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多