如何使用 LinQ 提高性能

本文关键字:高性能 LinQ 何使用 | 更新日期: 2023-09-27 18:30:45

我有这个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;

然后使用它们。

谢谢所有的建议。

如何使用 LinQ 提高性能

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

你担心是对的。每次访问查询时,查询都会重新执行,因为结果可能会更改。但是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);
然后,第一行创建查询,

第二行执行查询并存储结果,第三行和第四行报告存储的结果。

在您提供的代码中,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()有效地执行了同样的事情。

如果每次我打电话给IPI的每个成员时,我都会感到沮丧,LinQ 每次执行还是在我分配时第一次执行?

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

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

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

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

因此,当您使用该对象时,不会再执行任何内容