【问题标题】:Return multiple rows from a select new using linq使用 linq 从 select new 中返回多行
【发布时间】:2012-11-08 12:51:18
【问题描述】:

我们需要将数据从表中的行转置到输出表,以便为输入表中的每一行返回多行。 在输出的每一行中提取数据的逻辑取决于输入行的给定列中是否存在值。

例如

输入表

A、B、C、D、E、F

输出表

A, B, C, [如果 D 中存在值,则对 D 中的值进行一些操作]

A, B, C, [如果 E 中存在值,则对 E 中的值进行一些操作]

A, B, C, [如果 F 中存在值,则对 F 中的值进行一些操作]

为此,我打算这样做:

private IEnumerable<OutputRow> BuildOutputTable(DataTable inputTable)
{
    var outputRows = from inputRow in inputTable.AsEnumerable()
                     select new outputRow(inputRow, *delegateToProcessor*);
    return gbbOutputRows;
}

但这需要我对每个附加值列进行迭代。 我可以避免这种情况并只传递一个委托,以便“选择新输出行”返回多行吗?

【问题讨论】:

  • 您的输入表 - 逗号分隔的列表代表 1 行 6 列还是 6 行 1 列?同样,您的输出表是 3 行 4 列吗?不是很清楚。
  • @Jamiec :输入表为 6 列,输出表为 4 列。只是想表明每个输入行会产生 3 个输出行,除了计算列之外具有相同的值。

标签: c# .net linq linq-to-objects


【解决方案1】:

我愿意:

var DRows = from inputRow in inputTable.AsEnumerable()
                 where inputRow.D == 'some value'
                 select new outputRow(inputRow, *delegateToProcessor*)

var ERows = from inputRow in inputTable.AsEnumerable()
                 where inputRow.E == 'some value'
                 select new outputRow(inputRow, *delegateToProcessor*)

var FRows = from inputRow in inputTable.AsEnumerable()
                 where inputRow.F == 'some value'
                 select new outputRow(inputRow, *delegateToProcessor*)

return DRows.Union(ERows).Union(FRows);

【讨论】:

  • 我觉得ConcatUnion 好。
【解决方案2】:

创建一个这样的函数:

public IEnumerable<OutputRow> GetOutputRows(InputRow input)
{
    if ( ** some condition on input.D ** )
        yield return new OutputRow(inputRow, *delegateToProcessor*);
    if ( ** some condition on input.E ** )
        yield return new OutputRow(inputRow, *delegateToProcessor*);
    if ( ** some condition on input.F ** )
        yield return new OutputRow(inputRow, *delegateToProcessor*);
}

你的查询是这样的:

var outputRows = from inputRow in inputTable.AsEnumerable()
                 from row2 in GetOutputRows(inputRow)
                 select row2;

【讨论】:

    【解决方案3】:

    linq的select语句一次只能选择1个对象。但是,您可以选择一个组,然后进行联合。
    结果看起来像这样:

            public static void test()
            {
                var data = new List<String>{"a","b","c","d"};
                var outputRows = from inputRow in data
                                 select Expand(inputRow);
                var result = new List<String>();
                outputRows.ToList().ForEach(r=>result = r.Union(result).ToList());
            }
    
            private static List<String> Expand(string data)
            {
                var subdata = new List<String>();
                subdata.Add(data + "1");
                subdata.Add(data + "2");
                return subdata;
            }
    

    【讨论】:

      【解决方案4】:

      这个呢:

      private IEnumerable<OutputRow> BuildOutputTable(DataTable inputTable)
      {
          var tmp = from inputRow in inputTable.AsEnumerable()
                    select new { x = getProcessedRows(inputRow)};
          var outputRows = tmp.SelectMany(x=>x.x);
          return outputRows;
      }
      
      private IEnumerable<OutputRow> getProcessedRows(YourInputRowType inputRow)
      {
          List<OutputRow> ret = new List<OutputRow>()
          /* some logic here to generate the output rows for this input row */
          return ret;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-12-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-06-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多