我有这个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;
然后使用它们。
感谢所有建议。
答案 0 :(得分:7)
首先,停止在你的代码中出现。
你是对的。每次访问时都会执行查询 fresh ,因为结果可能会发生变化。但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);
然后第一行创建查询,第二行执行查询并存储结果,第三行和第四行报告存储的结果。
答案 1 :(得分: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()
会有效地做同样的事情。
答案 2 :(得分:1)
如果我每次打电话给IPI的每个成员,LinQ,我都会发出警告 每次或仅在我分配时第一次执行?
不,查询只执行一次 - IPI
是具有一堆原始属性(实际上是小数)的匿名类型的实例。此对象不再与查询相关联 - 您的查询已执行并作为First()
扩展方法的结果返回此对象,该方法强制立即执行并返回输入集合中的第一个项目。
答案 3 :(得分:1)
Eric Lippert的回答解释了你想要的一切。但是,如果您想进一步优化,可以尝试使用CompiledQuery.Compile方法来存储和重用查询。
有关更多信息,请查看msdn。你可以从这里开始: http://msdn.microsoft.com/cs-cz/library/bb399335.aspx
答案 4 :(得分:0)
First()方法执行linq查询并返回第一个对象 此对象的类型与您使用的任何其他对象类似,唯一的区别是类定义是由编译器编写的。
因此,当您使用对象
时,不再执行任何操作