1

我有这个 LinQ:

var IPI = item.INV_TAXES.Where(t => t.TAXTYPES.TAXNAME == "IPI")
                        .Select(t => new {TOT_AMT = t.TAXVALUE, t.TAXFACTOR, t.TAXBASE})
                        .First();

然后在代码中我调用下一行大约 10 次:

PerformSomeCalculation(IPI.TOT_AMT);
PerformAnotherStuff(IPI.TOT_AMT,IPI.TAXVALUE);
PerformSomethingElse(IPI.TAXBASE);

我想知道每次我调用 IPI 的每个成员时,LinQ 都会执行还是只是在我第一次分配它时执行?

首先将 IPI 成员分配给变量会更好吗?

decimal IPI_TOT_AMT = IPI.TOT_AMT,
        IPI_TAXVALUE = IPI.TAXVALUE,
        IPI_TAXBASE = IPI.TAXBASE;

然后使用它们。

感谢所有的建议。

4

5 回答 5

7

首先,停止在你的代码中大喊大叫。

你的担心是对的。每次访问时都会重新执行查询因为结果可能会发生变化。但结果不是查询,而是一个值。First

也就是说,如果你这样做:

var query = whatever.Where(whatever).Select(whatever);
Console.WriteLine(query.First());
Console.WriteLine(query.First());

然后查询由第一行创建,由第二行执行,并由第三行再次执行。查询不知道第二次调用时第一个结果是否不同First,因此再次运行查询。

相反,如果你这样做:

var query = whatever.Where(whatever).Select(whatever);
var first = query.First();
Console.WriteLine(first);
Console.WriteLine(first);

然后第一行创建查询,第二行执行查询并存储结果,第三行和第四行报告存储的结果。

于 2012-04-10T22:27:31.907 回答
4

在您提供的代码中,LINQ 查询只会在您调用该.First()方法时运行。

通过在访问变量之前将成员分配给变量,不会有明显的性能改进。

请注意,并非所有 LINQ 语句都如此。例如,如果您说过:

var IPIs = item.INV_TAXES.Where(t => t.TAXTYPES.TAXNAME == "IPI")
                     .Select(t => new {TOT_AMT = t.TAXVALUE, t.TAXFACTOR, t.TAXBASE});

...然后将 IPI 传递给几种方法,您最终可能会得到单独的数据库往返。为了避免该问题,您将.ToList()在分配变量之前调用强制立即评估。但在这种情况下,调用.First()有效地做同样的事情。

于 2012-04-10T22:18:44.963 回答
1

如果每次调用 IPI 的每个成员时,LinQ 每次都执行还是仅在我分配它的第一次执行?

不,查询只执行一次- IPI是具有一堆原始属性(实际上是小数)的匿名类型的实例。此对象不再连接到查询 - 您的查询已执行并作为扩展方法的结果返回此对象,该First()扩展方法强制立即执行并返回输入集合中的第一项。

于 2012-04-10T22:18:51.333 回答
1

Eric Lippert 的回答解释了你想要的一切。但是,如果您想进一步优化,可以尝试使用 CompiledQuery.Compile 方法来存储和重用查询。

有关详细信息,请查看 msdn。你可以从这里开始:http: //msdn.microsoft.com/cs-cz/library/bb399335.aspx

于 2013-01-14T11:24:49.180 回答
0

First() 方法执行 linq 查询并返回第一个对象 该对象的类型与您使用的任何其他对象一样,唯一的区别是类定义是由编译器编写的。

因此,当您使用该对象时,不再执行任何操作

于 2012-04-10T22:20:44.320 回答