如何使用 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;
然后使用它们。
谢谢所有的建议。
首先,停止在你的代码中大喊大叫。
你担心是对的。每次访问查询时,查询都会重新执行,因为结果可能会更改。但是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 查询并返回第一个对象此对象的类型与您使用的任何其他对象一样,唯一的区别是类定义由编译器编写。
因此,当您使用该对象时,不会再执行任何内容