如何在LINQ表达式中预先设置变量?

时间:2014-10-17 08:30:48

标签: c# linq

我正在根据数据行创建一个对象数组,如下所示。在工作的时候,通过从行中的单元格中拉出相同的值,我做了一些操作,这让我感到困扰。通常,这个东西会在循环之前预先准备好,然后在这里设置多次,我不会获得该值,直到实际迭代中。

return table.Rows.Cast<DataRow>()
  .Select(row => new Beep
    {
      Uno = HeavyComputation(row["ID"]),
      Duo = HeavyComputation(row["ID"])
    }).ToList();

能否以更好的方式解决这个问题?有点像(只是在这里做白日梦)吗?

return table.Rows.Cast<DataRow>()
  .Preset("int preComputed = HeavyComputation(row['ID'])"
  .Select(row => new Beep
    {
      Uno = preComputed,
      Duo = preComputed
    }).ToList();

请注意,实际示例有点复杂,上面的代码是问题的最小例证。我认识到 Uno Duo 在这里是多余的。 :)

2 个答案:

答案 0 :(得分:5)

您可以这样做:

return table.Rows.Cast<DataRow>()
  .Select(row => {
    long preComputed = HeavyComputation(row["ID"]); 
    return new Beep
    {
      Uno = preComputed,
      Duo = preComputed
    };
  });

在这种情况下,Select的参数是Func<DataRow, Beep>。由于Func<>只是一个委托,因此您可以将匿名方法传递给Select,如上例所示。你也可以这样做:

public Beep TransformToBeep(DataRow dr)
{
    //Do a lot of work here

    return new Beep { ... };
}

然后在你的Select中写一下:

 return table.Rows.Cast<DataRow>().Select(TransformToBeep).ToList();

答案 1 :(得分:4)

在查询表达式中,您可以使用let

return from DataRow row in table.Rows
       let preComputed = HeavyComputation(row["ID"])
       select new Beep
       {
           // Use row and preComputed here
       };

要在非查询表达式中具有相同的效果,您可以使用多个Select调用:

return table.Rows.Cast<DataRow>()
            .Select(row => new { row, preComputed = HeavyComputation(row["ID"]) })
            // Other stuff here if you want
            .Select(pair => new Beep {
                        Uno = pair.preComputed,
                        Duo = pair.preComputed,
                        Trio = pair.Row[...]
                    });

如果您在最终preComputed中需要Select,则可以使用:

return table.Rows.Cast<DataRow>()
            .Select(row => HeavyComputation(row["ID"]))
            .Select(preComputed => new Beep {
                        Uno = preComputed,
                        Duo = preComputed
                    });

如果你很高兴有声明lambda(而不是表达lambdas),那么你当然可以使用Klaus的方法。请记住,虽然LINQ to SQL之类的东西不起作用,但它只适用于Enumerable,语句lambdas无法转换为表达式树。