简体   繁体   English

如何使用 LinQ 来提高性能

[英]How to use LinQ to increase performance

I have this LinQ:我有这个 LinQ:

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

Then after in the code I call the next lines about 10 times:然后在代码中我调用下一行大约 10 次:

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

I wonder if everytime that I call each member of IPI, the LinQ executes or just the first time when I assign it?我想知道每次调用 IPI 的每个成员时,LinQ 是否执行,或者只是第一次分配它?

Is it better to assign the IPI members to a variable first?首先将 IPI 成员分配给变量是否更好?

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

And then use them.然后使用它们。

Thanks for all the advises.感谢所有的建议。

First off, STOP SHOUTING IN YOUR CODE.首先,停止在您的代码中大喊大叫。

You are right to be concerned.你的担心是对的。 A query is executed fresh every time you access it, because the results might change.每次访问查询时都会重新执行查询,因为结果可能会发生变化。 But the result of First is not a query, it is a value.但是First的结果不是查询,而是一个值。

That is, if you did this:也就是说,如果您这样做:

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

Then the query is created by the first line, executed by the second line, and executed again by the third line.然后查询由第一行创建,由第二行执行,并由第三行再次执行 The query does not know whether the first result is different the second time you call First , so it runs the query again.查询不知道您第二次调用First时第一个结果是否不同,因此它再次运行查询。

By contrast, if you do this:相比之下,如果您这样做:

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

Then the first line creates the query, the second line executes the query and stores the result, and the third and fourth lines report the stored result.然后第一行创建查询,第二行执行查询并存储结果,第三和第四行报告存储的结果。

In the code you provided, the LINQ query will only run when you call the .First() method.在您提供的代码中,LINQ 查询只会在您调用.First()方法时运行。

There will be no noticeable performance improvement by assigning the members to variables before accessing them.在访问成员之前将成员分配给变量不会有明显的性能改进。

Note that this is not always the case with all LINQ statements.请注意,并非所有 LINQ 语句都是如此。 For example, if you had said:例如,如果你说:

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

... and then passed IPIs into several methods, you would likely end up with separate database round-trips. ... 然后将 IPI 传递给几种方法,您可能最终会进行单独的数据库往返。 In order to avoid that issue, you would call .ToList() to force immediate evaluation before assigning the variable.为了避免该问题,您可以调用.ToList()以在分配变量之前强制立即评估。 But in this case calling .First() effectively does the same thing.但在这种情况下调用.First()有效地做同样的事情。

I wounder if everytime that I call each member of IPI, the LinQ executes everytime or just the first time when I assign it?如果每次我调用 IPI 的每个成员时,LinQ 每次都执行还是第一次执行,我会感到很痛苦吗?

No, the query is only performed once - IPI is an instance of an anonymous type with a bunch of primitive properties (decimals in fact).不,查询只执行一次IPI是一个匿名类型的实例,具有一堆原始属性(实际上是小数)。 This object is not connected to a query anymore - your query was executed and returned this object as a result of the First() extension method which forces immediate execution and returns the first item in the input collection.此 object 不再连接到查询 - 您的查询已执行并返回此 object 作为First()扩展方法的结果,该方法强制立即执行并返回输入集合中的第一项。

The answer by Eric Lippert explains all that you wanted. Eric Lippert 的回答解释了你想要的一切。 However, if you want to go further in the optimalization, you can try using CompiledQuery.Compile method to store and reuse the queries.但是,如果你想在 go 中进一步优化,你可以尝试使用 CompiledQuery.Compile 方法来存储和重用查询。

For more information, check msdn.有关详细信息,请检查 msdn。 You can start here: http://msdn.microsoft.com/cs-cz/library/bb399335.aspx你可以从这里开始: http://msdn.microsoft.com/cs-cz/library/bb399335.aspx

The First() method execute the linq query and return the first object This object is typed like any other object you use, the only difference is that the class definition is written by the compiler. First() 方法执行 linq 查询并返回第一个 object 这个 object 的类型与您使用的任何其他 object 一样,唯一的区别是 class 定义是由编译器编写的。

So nothing is executed any more when you use the object因此,当您使用 object 时,不再执行任何操作

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM