The process of understanding PLINQ starts with an
understanding of LINQ. For this reason, an introduction to LINQ might
be helpful.
You are probably accustomed to building query commands for
conventional database sources. Here is a SQL query example in which the
SELECT and FROM clauses select the ISBN, FirstName, LastName, Title, and Publisher fields from the Books table in a SQL database. The Where clause filters the results and returns only the records where Lucerne Publishing is the publisher. The OrderBy clause sorts the records by the title of the book.
SELECT ISBN, FirstName, LastName, Title, Publisher FROM Books
WHERE Publisher="Lucerne Publishing" ORDER BY Title
As mentioned, one of the advantages of LINQ is the ability to apply
similar queries to a variety of domains. In the following code, the Book
class is an encapsulation of the operations and attributes of a book.
Using LINQ, you search through a collection of books as easily as
searching a SQL Server database. Here is the LINQ to Objects query of a
book collection.
from book in books where book.Publisher=="Lucerne Publishing"
orderby book.Title select book;
The LINQ query starts with the from clause and ends with the select clause—the reverse of the SQL query. The in clause is used differently than it is in SQL. In LINQ, the in
clause identifies the data source. The double equal sign (==), not a
single equal sign (=), signifies equality. There are other differences
as well; however, there is sufficient similarity that most people
familiar with a modern SQL language should become somewhat comfortable
with LINQ very quickly.
Here is an expanded example of a LINQ query.
var books = new[] {new Book{Publisher="Lucerne Publishing",
First="David",
Last="Hamilton",
Title="David Hamilton Book",
ISBN="ISBN Number" },
new Book{Publisher="Lucerne Publishing",
First="Stefan",
Last="Hesse",
Title="Stefan Hesse Book",
ISBN="ISBN Number"},
new Book{Publisher="Lucerne Publishing",
First="Mike",
Last="Ray",
Title="Mike Ray Book",
ISBN="ISBN Number"},
new Book{Publisher="Lucerne Publishing",
First="Nuno",
Last="Bento",
Title="Nuno Bento Book",
ISBN="ISBN Number"}};
var titles=from book in books.AsParallel() where book.Publisher=="Lucerne Publishing"
orderby book.Title select book;
The preceding example returns an array of books. You can read the LINQ query as follows: From the books collection, return each book where the book.Publisher attribute is Lucerne Publishing. Sort the results by the book.Title attribute.
LINQ queries do not execute immediately. In fact, they don’t execute until you iterate the result, a process called deferred execution.
Every time you iterate the query results, LINQ reapplies the query
operation. For this reason, successive queries might generate different
results, because the underlying data might have changed. There are
exceptions, such as in a reduction, where a LINQ query returns a scalar
value. LINQ queries that return a scalar value are executed immediately.
This tutorial demonstrates deferred execution. You will create a LINQ query and then iterate the results. In the Where
clause, you will display a message. The message is displayed when the
results are iterated and not when the LINQ query is defined. This
demonstrates that the query is not executed until the results are
iterated.
Execute a LINQ query and then iterate and display the results
-
Create a console application for Microsoft Visual C# in Microsoft Visual Studio 2010. By default, C# projects include a using statement for the LINQ namespace, which is System.Linq. In the Main method, define an integer array that contains 10 values.
var intArray =new [] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
-
Next, use a LINQ query to return the array values greater than five.
Write the LINQ query by using the imperative syntax. You can then write
the Where clause as a
lambda expression to perform the appropriate selection. The lambda
expression accepts a single variable, the array index. The Where method (as well as other LINQ methods) is implemented as an extension method of the IEnumerable type. Lambda expressions for the Where method must return true or false. Returning true selects the current element, and returning false excludes the element.
var numbers = intArray.Where((index) =>
-
In the lambda expression, if the current array element is greater than five, return true. Otherwise, return false. If it is true, also display the value of the current element.
if (intArray[index] > 5)
{
Console.WriteLine("intArray[{0}]={1}",
index, intArray[index]);
return true;
}
else
{
return false;
}
-
Iterate the results in a foreach loop. Just prior to the foreach method, display a message that shows the location where the program is executing. In the foreach loop, do nothing!
Because of deferred execution, the LINQ query will be performed at this
point, displaying the values of the selected items in the Where clause.
-
At the end of the program, the Console.ReadLine method prevents the program from ending prematurely. You might also want to display a helpful message to the user.
-
Build and run the program.
Here is the complete application.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Deferred
{
class Program
{
static void Main(string[] args)
{
var intArray =new [] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
var numbers = intArray.Where((index) =>
{
if (intArray[index] > 5)
{
Console.WriteLine("intArray[{0}]={1}",
index, intArray[index]);
return true;
}
else
{
return false;
}
});
Console.WriteLine("Before foreach method.");
foreach (var number in numbers)
{
// no code
}
Console.WriteLine("Press Enter to Continue");
Console.ReadLine();
}
}
}
The following image shows the output for the application. Notice that nothing is displayed before the foreach loop. The results are displayed after the Where method actually executes, which occurs inside the foreach loop.
You now have a basic understanding of LINQ and are ready to explore PLINQ.