使用linq从select new返回多行

时间:2012-11-08 12:51:19

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

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

例如

输入表

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;
}

但是这需要我为每个附加值列进行迭代。 我可以避免这种情况,只是传递一个委托,以便'select new outputrow'返回多行吗?

4 个答案:

答案 0 :(得分: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);

答案 1 :(得分:1)

创建一个这样的函数:

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;

答案 2 :(得分:0)

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;
        }

答案 3 :(得分:0)

怎么样:

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;
}