When a LINQ query execution is deferred, when it is executed immediately, and the query is reused

Source: Internet
Author: User

Classic examples of deferred execution :

We can see with select ++i that the query is executed at foreach time.

public static void Linq99 ()
{
int[] numbers = new int[] {5, 4, 1, 3, 9, 8, 6, 7, 2, 0};
int i = 0;
var q = from N in numbers select ++i;
foreach (Var v in Q)
Console.WriteLine ("V = {0}, I = {1}", V, i);
}

Output Result:

v = 1, i = 1
v = 2, i = 2
v = 3, i = 3
v = 4, i = 4
v = 5, i = 5
v = 6, I = 6
v = 7, i = 7
v = 8, i = 8
v = 9, i = 9
v = ten, I = 10

Each time foreach iterates, the value of the select is the same as the value of the current I.

Classic examples of immediate execution:

public static void Linq99 ()
{
int[] numbers = new int[] {5, 4, 1, 3, 9, 8, 6, 7, 2, 0};
int i = 0;
var q = (from N in numbers select ++i). ToList ();
foreach (Var v in Q)
Console.WriteLine ("V = {0}, I = {1}", V, i);
}

Execution Result:

v = 1, i = 10
v = 2, i = 10
v = 3, i = 10
v = 4, i = 10
v = 5, i = 10
v = 6, i = 10
v = 7, i = 10
v = 8, i = 10
v = 9, i = 10
v = ten, I = 10

The only difference between this example code and the example code for deferred execution is that there is one more. ToList ();
This can also prove the principle we mentioned earlier:

It's only when it's used. Query execution

Because. ToList (); exists and is used here, so the query is executed here instead of executing the query in foreach. Notice that the result of this time is an array. See the following examples.

A special case of execution: repeated execution

Take a look at the following example:

Query for a number less than 3 in an int array.

In the following example, after the first query, the data source is modified, and then the second query, we can see the second time we do not need to do

Lownumbers = from n in numbers where n <= 3 select N; Such a definition, instead of using foreach directly (int n in lownumbers). The other two return results are different because we
After the first query, the data source was modified.

public static void Linq101 ()
{
int[] numbers = new int[] {5, 4, 1, 3, 9, 8, 6, 7, 2, 0};
var lownumbers = from N in numbers where n <= 3 select N;
Console.WriteLine ("First Run numbers <= 3:");
foreach (int n in lownumbers)
Console.WriteLine (n);

for (int i = 0; i <; i++)
Numbers[i] =-numbers[i];

Console.WriteLine ("Second Run numbers <= 3:");
foreach (int n in lownumbers)
Console.WriteLine (n);
}

Output Result:

First run numbers <= 3:
1
3
2
0
Second Run numbers <= 3:
-5
-4
-1
-3
-9
-8
-6
-7
-2
0

Let's look at a few more examples to deepen our understanding of query execution:

Another example of repeating a query:

public static void Linq102 ()
{
int[] numbers = new int[] {5, 4, 1, 3, 9, 8, 6, 7, 2, 0};
int i = 0;
var q = from N in numbers select ++i;
foreach (Var v in Q)
Console.WriteLine ("V = {0}, I = {1}", V, i);
foreach (Var v in Q)
Console.WriteLine ("V = {0}, I = {1}", V, i);
}

Execution Result:

v = 1, i = 1
v = 2, i = 2
v = 3, i = 3
v = 4, i = 4
v = 5, i = 5
v = 6, I = 6
v = 7, i = 7
v = 8, i = 8
v = 9, i = 9
v = ten, I = 10
v = one, I = 11
v = A, I = 12
v = A, I = 13
v = +, I = 14
v = A, I = 15
v = +, I = 16
v = +, I = 17
v =, i = 18
v = +, I = 19
v = A, I = 20

An immediate query that executes only once:

public static void Linq102 ()
{
int[] numbers = new int[] {5, 4, 1, 3, 9, 8, 6, 7, 2, 0};
int i = 0;
var q = (from N in numbers select ++i). ToList ();
foreach (Var v in Q)
Console.WriteLine ("V = {0}, I = {1}", V, i);
foreach (Var v in Q)
Console.WriteLine ("V = {0}, I = {1}", V, i);
}

Execution Result:

v = 1, i = 10
v = 2, i = 10
v = 3, i = 10
v = 4, i = 10
v = 5, i = 10
v = 6, i = 10
v = 7, i = 10
v = 8, i = 10
v = 9, i = 10
v = ten, I = 10
v = 1, i = 10
v = 2, i = 10
v = 3, i = 10
v = 4, i = 10
v = 5, i = 10
v = 6, i = 10
v = 7, i = 10
v = 8, i = 10
v = 9, i = 10
v = ten, I = 10

Those functions cause the query to be executed immediately:

The following extension functions will cause LINQ to execute immediately. and executes only once.

. ToArray ();

. ToList ();

. ToDictionary (k = k);

Like what:

public static void Linq102 ()
{
int[] numbers = new int[] {5, 4, 1, 3, 9, 8, 6, 7, 2, 0};
int i = 0;
var q = (from N in numbers select ++i). ToDictionary (k = k);
foreach (Var v in Q)
Console.WriteLine ("V = {0}, I = {1}", V, i);
foreach (Var v in Q)
Console.WriteLine ("V = {0}, I = {1}", V, i);
}

The output is:

v = [1, 1], I = 10
v = [2, 2], I = 10
v = [3, 3], I = 10
v = [4, 4], i = 10
v = [5, 5], I = 10
v = [6, 6], I = 10
v = [7, 7], I = 10
v = [8, 8], I = 10
v = [9, 9], I = 10
v = [Ten, ten], I = 10
v = [1, 1], I = 10
v = [2, 2], I = 10
v = [3, 3], I = 10
v = [4, 4], i = 10
v = [5, 5], I = 10
v = [6, 6], I = 10
v = [7, 7], I = 10
v = [8, 8], I = 10
v = [9, 9], I = 10
v = [Ten, ten], I = 10

Summary:

Q : Through the above examples, how do we understand LINQ when will the query be executed?

A : LINQ the query execution follows these guidelines:

1 , in general (except as stated in the third article below), LINQ Are deferred, for reasons: DLinq as an example, the later executed, the clearer the understanding of the business logic DLinq the smaller the query pressure on the database. The more things the compiler can do with LINQ query optimizations.

2 , because it is deferred execution, which is called when the time to execute. This invocation is executed once, so that it has the ability to repeat, see the previous examples of repeated executions. This repetition does not need to be written on one side of the query statement.

3 , if we use the query results in the query ToArray , ToList , todictionary these are transformed into collections of extension methods. The object used at this time is a separate collection array, not a LINQ query, so there will be no multiple queries at this point, but only one query.

That is: var q = from N in numbers select ++i; In this case, we can assume that it records not the result to the right of the equal sign, but rather the expression to the right of the record.

and var q = (from N in numbers select ++i). ToDictionary (k = k); Such a statement we record is the result of the calculation on the right side of the equals sign, not the expression.

To understand the above explanation, we can look at two more examples:

public static void Linq102 ()
{
int[] numbers = new int[] {5, 4, 1, 3, 9, 8, 6, 7, 2, 0};
int i = 0;
var q = from N in numbers select ++i;
var qq = q.todictionary (k = k);
foreach (Var v in Q)
Console.WriteLine ("V = {0}, I = {1}", V, i);
foreach (Var v in Q)
Console.WriteLine ("V = {0}, I = {1}", V, i);
}

Output Result:

v = one, I = 11
v = A, I = 12
v = A, I = 13
v = +, I = 14
v = A, I = 15
v = +, I = 16
v = +, I = 17
v =, i = 18
v = +, I = 19
v = A, I = 20
v = +, I = 21
v = A, I = 22
v = max, i = 23
v =, I = 24
v = +, I = 25
v = A, I = 26
v = +, I = 27
v = +, I = 28
v =, i = 29
v = +, I = 30

and

public static void Linq102 ()
{
int[] numbers = new int[] {5, 4, 1, 3, 9, 8, 6, 7, 2, 0};
int i = 0;
var q = from N in numbers select ++i;
var qq = q.todictionary (k = k);
foreach (Var v in QQ)
Console.WriteLine ("V = {0}, I = {1}", V, i);
foreach (Var v in QQ)
Console.WriteLine ("V = {0}, I = {1}", V, i);
}

The output is:

v = [1, 1], I = 10
v = [2, 2], I = 10
v = [3, 3], I = 10
v = [4, 4], i = 10
v = [5, 5], I = 10
v = [6, 6], I = 10
v = [7, 7], I = 10
v = [8, 8], I = 10
v = [9, 9], I = 10
v = [Ten, ten], I = 10
v = [1, 1], I = 10
v = [2, 2], I = 10
v = [3, 3], I = 10
v = [4, 4], i = 10
v = [5, 5], I = 10
v = [6, 6], I = 10
v = [7, 7], I = 10
v = [8, 8], I = 10
v = [9, 9], I = 10
v = [Ten, ten], I = 10

When a LINQ query execution is deferred, when it is executed immediately, and the query is reused

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.