lecture #12 linq introduction linq is short for l in...

26
Visual C# - Penn P. Wu, PhD. 380 Lecture #12 LINQ Introduction LINQ is short for language integrated query. It is a declarative syntax form that implants the query capabilities directly into the C# language. A query is an expression that retrieves data from a data source. Queries are usually expressed in a specialized query language such as the SQL (structure query language). However, unlike Oracle, MySql, or Microsoft SQL, a LINQ query is managed like classes, methods, events and so on. The following lines need to be included in the C# source code in order to use LINQ. using System.Collections.Generic; using System.Linq; LINQ query syntax According to Microsoft, all LINQ query operations consist of three distinct actions: (1). Obtain the data source; (2). Create the query; and (3). Execute the query. The following example shows how the three parts of a query operation are expressed in a C# code. This example uses an integer array as a data source. In its query, it uses the modulus operator to set criteria: v % 2 == 0. Apparently, LINQ queries are SQL-like statements; however, it is necessary to note that the type of LINQ queries is IEnumerable<T>. In the following example, the data source is an “int” array. using System.Windows.Forms; using System.Collections.Generic; using System.Linq; class myLinq { static void Main() { // Data source. int[] x = new int[7] { 0, 1, 2, 3, 4, 5, 6 }; // Query creation. even is IEnumerable<int> type var even = from v in x where (v % 2) == 0 select v; // Query execution. string str = ""; foreach (int v in even) { str += v + "\n"; } MessageBox.Show(str); } } The output looks:

Upload: others

Post on 20-Sep-2020

10 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Lecture #12 LINQ Introduction LINQ is short for l in qstudents.cypresscollege.edu/cis218/lc12.pdf · Visual C# - Penn P. Wu, PhD. 380 Lecture #12 LINQ Introduction LINQ is short for

Visual C# - Penn P. Wu, PhD. 380

Lecture #12 LINQ

Introduction LINQ is short for language integrated query. It is a declarative syntax form that implants the

query capabilities directly into the C# language. A query is an expression that retrieves data

from a data source. Queries are usually expressed in a specialized query language such as the

SQL (structure query language). However, unlike Oracle, MySql, or Microsoft SQL, a LINQ

query is managed like classes, methods, events and so on. The following lines need to be included in the C# source code in order to use LINQ.

using System.Collections.Generic;

using System.Linq;

LINQ query

syntax

According to Microsoft, all LINQ query operations consist of three distinct actions: (1). Obtain

the data source; (2). Create the query; and (3). Execute the query. The following example

shows how the three parts of a query operation are expressed in a C# code. This example uses

an integer array as a data source. In its query, it uses the modulus operator to set criteria: v % 2

== 0. Apparently, LINQ queries are SQL-like statements; however, it is necessary to note that

the type of LINQ queries is IEnumerable<T>. In the following example, the data source is an

“int” array.

using System.Windows.Forms;

using System.Collections.Generic;

using System.Linq;

class myLinq

{

static void Main()

{

// Data source.

int[] x = new int[7] { 0, 1, 2, 3, 4, 5, 6 };

// Query creation. even is IEnumerable<int> type

var even = from v in x

where (v % 2) == 0

select v;

// Query execution.

string str = "";

foreach (int v in even)

{

str += v + "\n";

}

MessageBox.Show(str);

}

}

The output looks:

Page 2: Lecture #12 LINQ Introduction LINQ is short for l in qstudents.cypresscollege.edu/cis218/lc12.pdf · Visual C# - Penn P. Wu, PhD. 380 Lecture #12 LINQ Introduction LINQ is short for

Visual C# - Penn P. Wu, PhD. 381

A LINQ query must begin with a from clause and must end with a select or group clause. The

following table provides two examples: one ends with select clause; the other ends with

group..by clause.

Select Group By using System;

using System.Windows.Forms;

using System.Collections.Generic;

using System.Linq;

class myLinq

{

static void Main()

{

double[] scores = { 69.5, 74.5,

42.3, 55.8, 91.3 };

var query =

from s in scores

orderby s

select s;

string str = "";

foreach (double s in query)

{

str += s * 0.95 + " ";

}

MessageBox.Show(str);

}

}

using System.Windows.Forms;

using System.Collections.Generic;

using System.Linq;

class myLinq

{

static void Main()

{

double[] scores = { 69.5, 74.5,

42.3, 55.8, 91.3 };

var query =

(from s in scores

orderby s

group s by (s >=

60)).Count();

MessageBox.Show(query+"");

}

}

Between the first from clause and the last select or group clause, it can contain one or more

clauses, such as where or orderby. In the above sample code, the orderby clause specifies how a collection should be ordered. A generic LINQ query may as well be (where collection

can be an array or a list):

IEnumerable<dataType> queryVaiableName =

from iterator in collection

where condition

select iterator

Interestingly, LINQ queries could be represented by the var keyword; therefore, the following

are actually the same. The condition specifies in the where clause is: s >= 60. The keyword

descending specifies the use of reversed order.

IEnumerable<int> var IEnumerable<int> query =

from score in scores

where s >= 60

orderby s descending

select s;

var query =

from s in scores

where s >= 60

orderby s descending

select s;

The following is a sample LINQ query that sorts the list (the data source) ascending.

using System.Windows.Forms;

using System.Collections.Generic;

using System.Linq;

Page 3: Lecture #12 LINQ Introduction LINQ is short for l in qstudents.cypresscollege.edu/cis218/lc12.pdf · Visual C# - Penn P. Wu, PhD. 380 Lecture #12 LINQ Introduction LINQ is short for

Visual C# - Penn P. Wu, PhD. 382

class myLinq

{

static void Main()

{

List<double> scores = new List<double>() { 69.5, 74.5, 42.3,

55.8, 91.3 };

IEnumerable<double> query =

from s in scores

orderby s

select s;

string str = "";

foreach (double x in query)

{

str += x + "\n";

}

MessageBox.Show(str);

}

}

In the above LINQ query, “query” is a query variable of the IEnumerable<T> type that stores a

query instead of the results of a query. The “s” is an iterator that represents each element of the

collection being retrieved by the query. This iterator can be named differently as long as the

name complies with the naming convention of C#.

The following example demonstrates how a string array and orderby keyword work collaboratively.

using System.Windows.Forms;

using System.Collections.Generic;

using System.Linq;

class myLinq

{

static void Main()

{

string[] words = { "cherry", "apple", "blueberry" };

var query =

from s in words

orderby s

select s;

string str = "";

foreach (var s in query)

{

str += s + "\n";

}

MessageBox.Show(str);

}

}

While C# array is a popular type of data source. LINQ data source could be a C# List, as shown

below.

using System.Windows.Forms;

using System.Collections.Generic;

Page 4: Lecture #12 LINQ Introduction LINQ is short for l in qstudents.cypresscollege.edu/cis218/lc12.pdf · Visual C# - Penn P. Wu, PhD. 380 Lecture #12 LINQ Introduction LINQ is short for

Visual C# - Penn P. Wu, PhD. 383

using System.Linq;

class myLinq

{

static void Main()

{

// Data source.

List<int> x = new List<int>() { 0, 1, 2, 3, 4, 5, 6 };

// Query creation. even is IEnumerable<int> type

var even = from v in x

where (v % 2) == 0

select v;

// Query execution.

string str = "";

foreach (int v in even)

{

str += v + "\n";

}

MessageBox.Show(str);

}

}

The following is another example that uses a string List as data source.

using System.Windows.Forms;

using System.Collections.Generic;

using System.Linq;

class myLinq

{

static void Main()

{

List<string> names = new List<string>() { "Jenny", "Jack",

"Jane", "Jimmy" };

var query =

(from s in names

where s == "Jane"

select s);

string str = "";

foreach (string x in query)

{

str += x + "\n";

}

MessageBox.Show(str);

}

}

A LINQ query is executed in a foreach statement, and foreach requires IEnumerable or

IEnumerable<T>. Therefore, it it possible to define the query inside the foreach structure, as

shown below.

using System.Windows.Forms;

using System.Collections.Generic;

using System.Linq;

class myLinq

Page 5: Lecture #12 LINQ Introduction LINQ is short for l in qstudents.cypresscollege.edu/cis218/lc12.pdf · Visual C# - Penn P. Wu, PhD. 380 Lecture #12 LINQ Introduction LINQ is short for

Visual C# - Penn P. Wu, PhD. 384

{

static void Main()

{

int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };

string str = "";

foreach (var i in (from n in numbers select n))

{

str += i + "\n";

}

MessageBox.Show(str + "");

}

}

Types that support IEnumerable<T> or a derived interface such as the generic IQueryable<T>

are called “queryable” types. Interestingly, you cannot declare a LINQ query as IQueryable<T> type. The following simply throws an error message.

using System.Windows.Forms;

using System.Collections.Generic;

using System.Linq;

class myLinq

{

static void Main()

{

List<double> scores = new List<double>() { 69.5, 74.5, 42.3,

55.8, 91.3 };

IQueryable<double> query = from s in scores orderby s select

s;

string str = "";

foreach (double x in query) { str += x + " "; }

MessageBox.Show(str + "");

}

}

The group..by clause enables programmers to group results based on a specified key. However,

the problem is that results take the form of a list of lists. Each element in the list is an object

that has a Key member and a list of elements that are grouped under that key. When you iterate

over a query that produces a sequence of groups, you must use a nested foreach loop. The outer loop iterates over each group, and the inner loop iterates over each group’s members. It takes

multiple foreach structures to resolve this problem, as shown below. If you must refer to the

results of a group operation, you can use the into keyword to create an identifier that can be

queried further

using System.Windows.Forms;

using System.Collections.Generic;

using System.Linq;

class myLinq

{

static void Main()

{

int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };

var query = from n in numbers

Page 6: Lecture #12 LINQ Introduction LINQ is short for l in qstudents.cypresscollege.edu/cis218/lc12.pdf · Visual C# - Penn P. Wu, PhD. 380 Lecture #12 LINQ Introduction LINQ is short for

Visual C# - Penn P. Wu, PhD. 385

group n by n % 5 into g

select new { k = g.Key, N = g };

string str = "";

foreach (var g in query)

{

str += "n%5 = " + g.k + " when n = ";

foreach (var x in g.N)

{

str += x + " ";

}

str += "\n";

}

MessageBox.Show(str);

}

}

Another problem is that the group..by clause returns a sequence of IGrouping<TKey,

TElement> objects that contain zero or more items that match the key value for the group. In

the above example, the instructor declares two variables, k and N, to represent TKey and

TElement. In this case, the index of every element is stored in the Key property while the

content of the element is stored in the N variable of IGrouping<TKey, TElement> object. The

compiler will infer value of the key to retrieve the values in the TElement. The following is

another example.

using System.Windows.Forms;

using System.Collections.Generic;

using System.Linq;

class myLinq

{

static void Main()

{

string[] words = { "apples", "blueberries", "oranges",

"bananas", "apricots"};

var query =

from w in words

group w by w[0] into fruit

select new { k = fruit.Key, F = fruit };

string str = "";

foreach (var fruit in query)

{

foreach (var v in fruit.F)

{

str += v + "\n";

}

}

MessageBox.Show(str + "");

}

}

Again, because the IGrouping<TKey, TElement> objects produced by a group query are

essentially a list of lists, you must use a nested foreach loop to access the items in each group.

The outer loop iterates over the group keys, and the inner loop iterates over each item in the

group itself. A group may have a key but no elements.

Page 7: Lecture #12 LINQ Introduction LINQ is short for l in qstudents.cypresscollege.edu/cis218/lc12.pdf · Visual C# - Penn P. Wu, PhD. 380 Lecture #12 LINQ Introduction LINQ is short for

Visual C# - Penn P. Wu, PhD. 386

Custom-make

function with

LINQ

One benefits for LINQ query to be managed like a class is that it allows the use of custom-

made functions in the query. The following code contains a function, named IsEven(), that

returns a bool value indicating whether or not a number is an even number. The result of

IsEven() is then used in the LINQ query to retrieve the matching data.

using System.Windows.Forms;

using System.Collections.Generic;

using System.Linq;

class myLinq

{

static void Main()

{

List<int> x = new List<int>() { 6, 4, 1, 8, 3, 9, 0, 2, 5,

7 };

var query =

from i in x

orderby i

select IsEven(i);

string str = "";

foreach (bool s in query)

{

str += s + "\n";

}

MessageBox.Show(str);

}

public static bool IsEven(int i)

{

return i % 2 == 0;

}

}

The output looks:

ToArray(),

ToList() and

ToDictionary() methods

The following example illustrates how to filter or restrict results by applying conditions with a

where clause. It returns all elements in the list whose values are even number. It also uses the

ToArray() method to convert a LINQ query to an array and the ToList() method to convert the query to a list.

using System.Windows.Forms;

using System.Collections.Generic;

using System.Linq;

Page 8: Lecture #12 LINQ Introduction LINQ is short for l in qstudents.cypresscollege.edu/cis218/lc12.pdf · Visual C# - Penn P. Wu, PhD. 380 Lecture #12 LINQ Introduction LINQ is short for

Visual C# - Penn P. Wu, PhD. 387

class myLinq

{

static void Main()

{

List<int> x = new List<int>() { 6, 4, 1, 8, 3, 9, 0, 2, 5,

7 };

IEnumerable<int> query =

from i in x

where i % 2 <= 0

orderby i

select i;

int[] even1 = query.ToArray();

List<int> even2 = query.ToList();

string str = "Array:\n";

for (int i=0; i<even1.Length; i++)

{

str += even1[i] + " ";

}

str += "\n\nList:\n";

foreach (int e in even2)

{

str += e + " ";

}

MessageBox.Show(str);

}

}

The above code also demonstrates how to use for and foreach loop to retrieve elements from

collections. The following code illustrates how to retrieves elements from a two-dimensional

array in LINQ.

using System.Windows.Forms;

using System.Collections.Generic;

using System.Linq;

class myLinq

{

static void Main()

{

int[,] arr = new int[,] {

{1, 2}, {3, 4},

{5, 6}, {7, 8},

{9, 10}, {11, 12} };

IEnumerable<int> query =

from int v in arr

select v;

string str = "";

foreach (int a in query)

{

str += a + "\n";

}

MessageBox.Show(str);

Page 9: Lecture #12 LINQ Introduction LINQ is short for l in qstudents.cypresscollege.edu/cis218/lc12.pdf · Visual C# - Penn P. Wu, PhD. 380 Lecture #12 LINQ Introduction LINQ is short for

Visual C# - Penn P. Wu, PhD. 388

}

}

The following code illustrates how to retrieve elements from a string type of 2D array.

using System.Windows.Forms;

using System.Collections.Generic;

using System.Linq;

class myLinq

{

static void Main()

{

string[,] arr = new string[,] {

{"apple", "orange"}, {"banana", "tangerine"}, {"grape",

"pineapple"}

};

IEnumerable<string> query =

from string v in arr

select v;

string str = "";

foreach (string a in query)

{

str += a + "\n";

}

MessageBox.Show(str);

}

}

By the same token, the following code illustrates how to retrieves elements from a 3-D array

using LINQ query.

using System.Windows.Forms;

using System.Collections.Generic;

using System.Linq;

class myLinq

{

static void Main()

{

int[,,] arr = new int[,,] {

{{1, 2, 3}, { 4, 5, 6}},

{{7, 8, 9}, {10, 11, 12}} };

IEnumerable<int> query =

from int v in arr

select v;

string str = "";

foreach (int a in query)

{

str += a + "\n";

}

MessageBox.Show(str);

}

}

Page 10: Lecture #12 LINQ Introduction LINQ is short for l in qstudents.cypresscollege.edu/cis218/lc12.pdf · Visual C# - Penn P. Wu, PhD. 380 Lecture #12 LINQ Introduction LINQ is short for

Visual C# - Penn P. Wu, PhD. 389

The following is a 3D array of string type.

using System.Windows.Forms;

using System.Collections.Generic;

using System.Linq;

class myLinq

{

static void Main()

{

string[,,] arr = new string[,,] {

{{"Chicago", "IL", "603"}, { "Houston", "TX", "361"}},

{{"Los Angeles", "CA", "213"}, {"Detroit", "MI", "472"}} };

IEnumerable<string> query =

from string v in arr

select v;

string str = "";

foreach (string a in query)

{

str += a + "\n";

}

MessageBox.Show(str);

}

}

A C# dictionary provides fast lookups with keys to get values. The following demonstrates how

to create a simple dictionary in C#.

using System;

using System.Windows.Forms;

using System.Collections.Generic;

class myDict

{

static void Main()

{

Dictionary<string, int> d = new Dictionary<string, int>();

d.Add("cat", 2);

d.Add("dog", 1);

d.Add("pig", 0);

d.Add("rat", -1);

string str = "";

foreach (var v in d)

{

str += v.Key + " : " + v.Value + "\n";

}

MessageBox.Show(str);

}

}

The Enumerable.ToDictionary<TSource, TKey> method creates a Dictionary<TKey, TValue>

from an IEnumerable<T> according to a specified key selector function. It is created based on

the Dictionary<TKey, TValue> generic class which provides a mapping from a set of keys to a

set of values. Each addition to the dictionary consists of a value and its associated key.

Page 11: Lecture #12 LINQ Introduction LINQ is short for l in qstudents.cypresscollege.edu/cis218/lc12.pdf · Visual C# - Penn P. Wu, PhD. 380 Lecture #12 LINQ Introduction LINQ is short for

Visual C# - Penn P. Wu, PhD. 390

Retrieving a value by using its key is very fast, close to O(1), because the Dictionary<TKey,

TValue> class is implemented as a hash table.

The following example uses ToDictionary to immediately evaluate a sequence and a related

key expression into a dictionary.

using System.Windows.Forms;

using System.Collections.Generic;

using System.Linq;

class myLinq

{

static void Main()

{

var score = new[] {new {Name = "Alice", Score = 50},

new {Name = "Bob" , Score = 40},

new {Name = "Cathy", Score = 45}};

var sd = score.ToDictionary(r => r.Name);

string str = "";

foreach (var s in sd )

{

str += s + "\n";

}

str += sd["Alice"] + "\n";

str += sd["Bob"] + "\n";

str += sd["Cathy"] + "\n";

MessageBox.Show(str);

}

}

LINQ

extension

methods

LINQ introduces many extension methods to the standard C# environment. These methods

work on Lists, arrays and collections that are not yet in memory. It is designed to make some

computational tasks easier. Compare the following two examples, one uses LINQ’s Average

extension method to average all the elements in an int array, the other does not. They produce

the same results, yet, the LINQ version is smaller in file size.

With LINQ Without LINQ using System.Windows.Forms;

using System.Linq;

class myLinq

{

static void Main()

{

int[] x = {1, 3, 5, 7, 9};

MessageBox.Show(x.Average() +

"");

}

}

using System.Windows.Forms;

class myLinq

{

static void Main()

{

int[] x = {1, 3, 5, 7, 9};

int sum = 0;

for (int i=0; i<x.Length; i++)

{

sum += x[i];

}

MessageBox.Show((sum/x.Length)

+ "");

}

}

Page 12: Lecture #12 LINQ Introduction LINQ is short for l in qstudents.cypresscollege.edu/cis218/lc12.pdf · Visual C# - Penn P. Wu, PhD. 380 Lecture #12 LINQ Introduction LINQ is short for

Visual C# - Penn P. Wu, PhD. 391

In additional to Average, LINQ provides several computational methods. These methods act

upon a certain query and simply return a calculated or queried value as result. The following

code demonstrates the use of System.Linq’s Min(), Max(), Sum(), Single(), Distinct() and

Count() methods. They all work with arrays or lists. The Count() extension method enumerates elements of an array or a list.

In the following example, the use of parentheses to enclose the query before the call to the

Count() method allows the use of a non-IEnumerable<T> variable to store the result.

using System.Windows.Forms;

using System.Collections.Generic;

using System.Linq;

class myLinq

{

static void Main()

{

double[] scores = { 69.5, 74.5, 42.3, 55.8, 91.3 };

int query =

(from s in scores

where s >= 60

select s).Count();

MessageBox.Show(query + " passed.");

}

}

Can work with the numerable.Distinct() method to return distinct elements from a sequence.

using System.Windows.Forms;

using System.Collections.Generic;

using System.Linq;

class myLinq

{

static void Main()

{

int[] x = { 2, 2, 3, 5, 5 };

int unique = x.Distinct().Count();

MessageBox.Show("There are " + unique + " differnet numbers in

the set.");

}

}

The following is another example of Distinct() method.

using System.Windows.Forms;

using System.Collections.Generic;

using System.Linq;

class myLinq

{

static void Main()

{

List<int> numbers = new List<int> { 21, 46, 46, 55, 17, 21,

55, 55 };

IEnumerable<int> unique = numbers.Distinct();

Page 13: Lecture #12 LINQ Introduction LINQ is short for l in qstudents.cypresscollege.edu/cis218/lc12.pdf · Visual C# - Penn P. Wu, PhD. 380 Lecture #12 LINQ Introduction LINQ is short for

Visual C# - Penn P. Wu, PhD. 392

string str = "";

foreach (int number in unique)

{

str += number + "\n";

}

MessageBox.Show(str);

}

}

A sample output looks:

The output is “3 passed.” because there are three elements matching the condition: s >= 60.

The following is another example that demonstrates how Count() works.

using System.Windows.Forms;

using System.Collections.Generic;

using System.Linq;

class myLinq

{

static void Main()

{

int[] x = {-9, 12, 25, 7, 0, 6, 3, 10, 17, 2, 5};

List<int> y = new List<int>() {11, 2, 8, 0, 5, 7, 3, -11, 24,

6};

string str = "Array x:\n";

str += "Min: " + x.Min() + "\nMax: " + x.Max() + "\n";

str += "Sum: " + x.Sum() + "\nCount: " + x.Count();

str += "\n\nList y:\n";

str += "Min: " + y.Min() + "\nMax: " + y.Max() + "\n";

str += "Sum: " + y.Sum() + "\nCount: " + y.Count();

MessageBox.Show(str);

}

}

These System.Linq methods apparently simplify Visual C# codes by eliminating the need to

write codes and algorithms for computing results.

All() is an extension method of bool type that returns true or false. It checks if all the elements

in a collection match a certain condition. The Any() methods determines if any element in a collection matches a certain condition. For example, the following uses the All() to check if all

the elements of an array and a list are positive values. It also uses the Any() method to return

true if only one of the element is negative.

using System.Windows.Forms;

using System.Collections.Generic;

using System.Linq;

Page 14: Lecture #12 LINQ Introduction LINQ is short for l in qstudents.cypresscollege.edu/cis218/lc12.pdf · Visual C# - Penn P. Wu, PhD. 380 Lecture #12 LINQ Introduction LINQ is short for

Visual C# - Penn P. Wu, PhD. 393

class myLinq

{

static void Main()

{

int[] x = {-9, 12, 25, 7, 0, 6, 3, 10, 17, 2, 5};

List<int> y = new List<int>() {11, 2, 8, 0, 5, 7, 3, -11, 24,

6};

bool result = x.All(i => i > 0); // array

str += result + "\n";

result = x.Any(i => i < 0);

str += result + "\n";

result = y.All(i => i > 0); // list

str += result + "\n";

result = y.Any(i => i < 0);

str += result + "\n";

MessageBox.Show(str);

}

}

The SequenceEqual extension method can compare two collections for equality and return true

or false. The two collections can be in any combination of: (1) array and array, (2) list and list,

and (3) array and list. The following sample demonstrates how to use the SequenceEqual()

method to compare an array and a list for equality.

using System.Windows.Forms;

using System.Collections.Generic;

using System.Linq;

class myLinq

{

static void Main()

{

string[] x = {"Winter", "Spring", "Summer", "Fall"};

List<string> y = new List<string>() {"Spring", "Summer",

"Fall", "Winter"};

MessageBox.Show(x.SequenceEqual(y) + "");

}

}

A sample output is:

False

The Aggregate() method applies a calculation to every element of an array or a list by using the

result of calculation prior to the current element as the first operand and the current element as

second operand.

using System.Windows.Forms;

using System.Collections.Generic;

using System.Linq;

class myLinq

{

static void Main()

Page 15: Lecture #12 LINQ Introduction LINQ is short for l in qstudents.cypresscollege.edu/cis218/lc12.pdf · Visual C# - Penn P. Wu, PhD. 380 Lecture #12 LINQ Introduction LINQ is short for

Visual C# - Penn P. Wu, PhD. 394

{

int[] x = {1, 2, 3, 4, 5, 6 };

string str = "";

str += x.Aggregate((i, j) => i*j) + "";

MessageBox.Show(str);

}

}

This code calculates i*j step by step from x[0] to x[x.length-1]. The steps are:

1 + 2 = 3

3 + 3 = 6

6 + 4 = 10

10 + 5 = 15

15 + 6 = 21

In the following example, the Aggregate() method continuously multiplies the successive element.

using System.Windows.Forms;

using System.Collections.Generic;

using System.Linq;

class myLinq

{

static void Main()

{

List<int> x = new List<int>() { 1, 2, 3, 4, 5, 6 };

string str = "";

str += x.Aggregate((i, j) => i*j) + "";

MessageBox.Show(str);

}

}

The steps of calculation are:

1 * 2 = 2

2 * 3 = 6

6 * 4 = 24

24 * 5 = 120

120 * 6 = 720

The following code throws an InvalidOperationException because the sequence is emitted by

OrderBy contains four elements, and the Single() demands exactly one element.

using System.Windows.Forms;

using System.Collections.Generic;

using System.Linq;

class myLinq

{

static void Main()

{

string[] colors = { "red", "green", "brown", "blue", "pink"};

var str = colors.OrderBy(c => c.Length).Single();

MessageBox.Show(str);

}

}

Page 16: Lecture #12 LINQ Introduction LINQ is short for l in qstudents.cypresscollege.edu/cis218/lc12.pdf · Visual C# - Penn P. Wu, PhD. 380 Lecture #12 LINQ Introduction LINQ is short for

Visual C# - Penn P. Wu, PhD. 395

To get the result “red”, you must use the First() method instead. First() method returns the first

element of a sequence. It is necessary to note that c.Length specifies the list to be ordered by

the length of every word.

colors.OrderBy(c => c.Length).First();

The OrderBy() method can sort the elements of a sequence in ascending order. However, in or

to order a sequence by the values of the elements themselves, it is necessary to specify the key

select with the format of: variable => Key.

Review

Question

1. The type of LINQ queries is __.

A. IEnumerable<T> B. IQueryable<T>

C. Numerable<T>

D. Queryable<T>

2. The output of the following is __.

string[] colors = { "red", "green", "blue", "brown", "pink",

"yellow" };

var str = colors.OrderBy (c => c.Length).Count();

MessageBox.Show(str + "");

A. str

B. 6

C. yellow

D. None of the above

3. Given the following LINQ statement, what is the data type of query?

string[] colors = { "red", "green", "blue", "brown", "pink",

"yellow" };

........

var query =

from c in colors

where c.Length > 4

orderby c.Length

select c;

A. int

B. string C. IEnumerable<string>

D. List<string>

4. Given the following LINQ code, the output is __.

List<double> scores = new List<double>() { 69.5, 74.5, 42.3,

55.8, 91.3 };

IEnumerable<double> query = from s in scores orderby s select s;

string str = "";

foreach (double x in query) { str += x + " "; }

MessageBox.Show(str + "");

A. 69.5 74.5 42.3 55.8 91.3

B. 42.3 55.8 69.5 74.5 91.3

Page 17: Lecture #12 LINQ Introduction LINQ is short for l in qstudents.cypresscollege.edu/cis218/lc12.pdf · Visual C# - Penn P. Wu, PhD. 380 Lecture #12 LINQ Introduction LINQ is short for

Visual C# - Penn P. Wu, PhD. 396

C. 91.3 74.5 69.5 55.8 42.3

D. 91.3 55.8 42.3 74.5 69.5

5. The output of the following is __.

List<double> scores = new List<double>() { 69.5, 74.5, 42.3,

55.8, 91.3 };

IQueryable<double> str = (from s in scores orderby s select

s).count();

MessageBox.Show(str + "");

A. 5

B. scores

C. An IOrderEnumerable type error

D. 91.3

6. The group..by clause returns a sequence of __ objects.

A. Grouping<TKey, TElement>

B. IGrouping<TKey, TElement>

C. IList<TKey, TElement>

D. IArray<TKey, TElement>

7. How many foreach structure do you need to process the following query of group..by clause?

string[] words = { "apples", "blueberries", "oranges",

"bananas", "apricots"};

var query = from w in words group w by w[0] into fruit select

new { k = fruit.Key, F = fruit };

A. 0

B. 1 C. 2

D. 3

8. Given the following code snippet, which is a valid LINQ query?

int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };

A. var query = from n in numbers select n;

B. IEnumerable<int> query = from n in numbers select n; C. Both A and B

D. None of the above

9. Given the following code snippet, which is the possible result?

string[] colors = { "red", "green", "blue", "brown", "pink",

"yellow" };

var str = colors.OrderBy(c => c.Length).Single();

MessageBox.Show(str);

A. 6

B. red

C. yellow

D. Exception thrown

10. Given the following code snippet, which is the possible result?

Page 18: Lecture #12 LINQ Introduction LINQ is short for l in qstudents.cypresscollege.edu/cis218/lc12.pdf · Visual C# - Penn P. Wu, PhD. 380 Lecture #12 LINQ Introduction LINQ is short for

Visual C# - Penn P. Wu, PhD. 397

string[] colors = { "red", "green", "blue", "brown", "pink",

"yellow" };

var str = colors.OrderBy(c => c.Length).First();

MessageBox.Show(str);

A. yellow

B. brown

C. blue D. red

Page 19: Lecture #12 LINQ Introduction LINQ is short for l in qstudents.cypresscollege.edu/cis218/lc12.pdf · Visual C# - Penn P. Wu, PhD. 380 Lecture #12 LINQ Introduction LINQ is short for

Visual C# - Penn P. Wu, PhD. 398

Lab #12 LINQ

Learning Activity #1: static vs. non-static functions

1. Create a new directory called C:\CIS218 if it does not exist.

2. Launch the Development Command Prompt.

3. Under the C:\cis218 directory, under the C:\cis218 directory, use Notepad to create a new source file called

lab12_1.cs with the following contents:

using System.Windows.Forms;

using System.Collections.Generic;

using System.Linq;

class myLinq

{

static void Main()

{

int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };

var query =

from x in numbers

where x < 5

select x;

string str = "Numbers < 5:\n";

foreach (var x in query)

{

str += x + "\n";

}

MessageBox.Show(str);

}

}

4. In the prompt, type csc /t:winexe lab12_1.cs and press [Enter] to compile the source code.

5. Test the program. A sample output looks:

6. Capture a screen shot similar to the above figures and paste it to the Word document named lab12.doc

(or .docx).

Learning Activity #2:

1. Under the C:\cis218 directory, use Notepad to create a new source file called lab12_2.cs with the following

contents:

using System.Windows.Forms;

using System.Collections.Generic;

using System.Linq;

Page 20: Lecture #12 LINQ Introduction LINQ is short for l in qstudents.cypresscollege.edu/cis218/lc12.pdf · Visual C# - Penn P. Wu, PhD. 380 Lecture #12 LINQ Introduction LINQ is short for

Visual C# - Penn P. Wu, PhD. 399

class myLinq

{

static void Main()

{

List<string> products = GetProductList();

products.Add(InputBox.Show("Which is the U.S. brand of smartphone?"));

var query =

from p in products

group p by p into g

select new { k = g.Key, Products = g };

string str = "";

foreach (var g in query)

{

foreach (var x in g.Products)

{

str += x + "\n";

}

}

MessageBox.Show(str);

}

private static List<string> GetProductList()

{

List<string> p = new List<string>();

p.Add("HTC");

p.Add("Nokia");

p.Add("Samsung");

p.Add("Song");

return p;

}

}

2. Test the program. A sample output looks:

and

3. Capture a screen shot similar to the above figures and paste it to the Word document named lab12.doc

(or .docx).

Learning Activity #3:

1. Under the C:\cis218 directory, use Notepad to create a new source file called lab12_3.cs with the following

contents:

using System;

using System.Windows.Forms;

using System.Drawing;

using System.Data;

using System.Collections.Generic;

using System.Linq;

Page 21: Lecture #12 LINQ Introduction LINQ is short for l in qstudents.cypresscollege.edu/cis218/lc12.pdf · Visual C# - Penn P. Wu, PhD. 380 Lecture #12 LINQ Introduction LINQ is short for

Visual C# - Penn P. Wu, PhD. 400

public class Form1 : Form

{

private TextBox textBox1;

private Label label2;

List<string> x;

public Form1()

{

this.Size = new Size(445, 150);

x = new List<string>();

Label label1 = new Label();

label1.Text = "Enter number:";

label1.Location = new Point(10, 10);

label1.Width = 90;

Controls.Add(label1);

textBox1 = new TextBox();

textBox1.Location = new Point(100, 10);

textBox1.Width = 150;

Controls.Add(textBox1);

label2 = new Label();

label2.Text = "";

label2.Location = new Point(10, 40);

label2.Width = ClientSize.Width - 20;

Controls.Add(label2);

Button button1 = new Button();

button1.Text = "Save";

button1.Location = new Point(260, 10);

button1.Click += new EventHandler(this.button1_Click);

Controls.Add(button1);

Button button2 = new Button();

button2.Text = "Show";

button2.Location = new Point(345, 10);

button2.Click += new EventHandler(this.button2_Click);

Controls.Add(button2);

}

private void button1_Click(Object sender, EventArgs e)

{

x.Add(textBox1.Text);

label2.Text += textBox1.Text + " ";

textBox1.Text = "";

}

private void button2_Click(Object sender, EventArgs e)

{

var query = from s in x

orderby s

select s;

string str = "";

foreach (var s in query)

{

str += s + "\n";

}

Page 22: Lecture #12 LINQ Introduction LINQ is short for l in qstudents.cypresscollege.edu/cis218/lc12.pdf · Visual C# - Penn P. Wu, PhD. 380 Lecture #12 LINQ Introduction LINQ is short for

Visual C# - Penn P. Wu, PhD. 401

str += "Min: " + x.Min() + "\n";

str += "Max: " + x.Max() + "\n";

str += "Count: " + x.Count();

MessageBox.Show(str);

}

[STAThread]

public static void Main()

{

Application.Run(new Form1());

}

}

2. Test the program. A sample output looks:

and

3. Capture a screen shot similar to the above figures and paste it to the Word document named lab12.doc

(or .docx).

Learning Activity #4:

1. Under the C:\cis218 directory, use Notepad to create a new source file called lab12_4.cs with the following

contents:

using System.Windows.Forms;

using System.Collections.Generic;

using System.Linq;

class myLinq

{

static void Main()

{

// 3D int array

int[,,] arr1 = new int[,,] {

{{1, 2, 3}, { 4, 5, 6}},

{{7, 8, 9}, {10, 11, 12}} };

IEnumerable<int> query1 =

from int v in arr1

select v;

string str = "";

foreach (int a in query1)

{

str += a + "\n";

}

// 3D string array

string[,,] arr2 = new string[,,] {

{{"Chicago", "IL", "603"}, { "Houston", "TX", "361"}},

Page 23: Lecture #12 LINQ Introduction LINQ is short for l in qstudents.cypresscollege.edu/cis218/lc12.pdf · Visual C# - Penn P. Wu, PhD. 380 Lecture #12 LINQ Introduction LINQ is short for

Visual C# - Penn P. Wu, PhD. 402

{{"Los Angeles", "CA", "213"}, {"Detroit", "MI", "472"}} };

IEnumerable<string> query2 =

from string v in arr2

select v;

int i = 0;

foreach (string a in query2)

{

if (i%3==2)

{

str += a + "\n";

}

else

{

str += a + ", ";

}

i++;

}

MessageBox.Show(str);

}

}

2. Test the program. A sample output looks:

3. Capture a screen shot similar to the above and paste it to the Word document named lab12.doc (or .docx).

Learning Activity #5:

1. Under the C:\cis218 directory, use Notepad to create a new source file called lab12_5.cs with the following

contents:

using System;

using System.Windows.Forms;

using System.Drawing;

using System.Data;

using System.Collections.Generic;

using System.Linq;

public class Form1 : Form

{

private TextBox textBox1;

private TextBox textBox2;

private TextBox textBox3;

DataTable dt;

DataRow row;

Page 24: Lecture #12 LINQ Introduction LINQ is short for l in qstudents.cypresscollege.edu/cis218/lc12.pdf · Visual C# - Penn P. Wu, PhD. 380 Lecture #12 LINQ Introduction LINQ is short for

Visual C# - Penn P. Wu, PhD. 403

public Form1()

{

Label label1 = new Label();

label1.Text = "Company ID:";

label1.Location = new Point(10, 10);

label1.Width = 75;

Controls.Add(label1);

textBox1 = new TextBox();

textBox1.Location = new Point(100, 10);

textBox1.Width = 150;

Controls.Add(textBox1);

Label label2 = new Label();

label2.Text = "Quantity:";

label2.Location = new Point(10, 40);

label2.Width = 75;

Controls.Add(label2);

textBox2 = new TextBox();

textBox2.Location = new Point(100, 40);

textBox2.Width = 150;

Controls.Add(textBox2);

Label label3 = new Label();

label3.Text = "Company Name:";

label3.Location = new Point(10, 70);

label3.Width = 90;

Controls.Add(label3);

textBox3 = new TextBox();

textBox3.Location = new Point(100, 70);

textBox3.Width = 150;

Controls.Add(textBox3);

Button button1 = new Button();

button1.Text = "Save";

button1.Location = new Point(260, 10);

button1.Click += new EventHandler(this.button1_Click);

Controls.Add(button1);

Button button2 = new Button();

button2.Text = "Show";

button2.Location = new Point(260, 40);

button2.Click += new EventHandler(this.button2_Click);

Controls.Add(button2);

// Creaete a Dataset and DataTable

DataSet ds = new DataSet("Customers");

dt = ds.Tables.Add("Orders");

DataColumn dc =

dt.Columns.Add("CID", typeof(Int32));

dt.Columns.Add("Qty", typeof(Int32));

dt.Columns.Add("CompanyName", typeof(string));

DataGridView dataGridView1 = new DataGridView();

dataGridView1.DataSource = new BindingSource(ds, "Orders");

dataGridView1.Location = new Point(10, 100);

dataGridView1.AutoSize = true;

Page 25: Lecture #12 LINQ Introduction LINQ is short for l in qstudents.cypresscollege.edu/cis218/lc12.pdf · Visual C# - Penn P. Wu, PhD. 380 Lecture #12 LINQ Introduction LINQ is short for

Visual C# - Penn P. Wu, PhD. 404

Controls.Add(dataGridView1);

this.Width = 425;

}

private void button1_Click(Object sender, EventArgs e)

{

row = dt.NewRow();

row["CID"] = Convert.ToInt32(textBox1.Text);

row["Qty"] = Convert.ToInt32(textBox2.Text);

row["CompanyName"] =textBox3.Text;

dt.Rows.Add(row);

}

// using LINQ to query from a DataTable

private void button2_Click(Object sender, EventArgs e)

{

var query = from s in dt.AsEnumerable()

select new { cid = s.Field<int>("CID"),

qty = s.Field<int>("Qty"),

cmp = s.Field<string>("CompanyName")};

string str = "";

foreach (var s in query)

{

str += s.cid + " " + s.qty + " " + s.cmp + "\n";

}

MessageBox.Show(str);

}

[STAThread]

public static void Main()

{

Application.Run(new Form1());

}

}

2. Test the program. Enter some records, and click Save to store them in the DataView. Click Show to display them in a message box. A sample output looks:

and

3. Capture a screen shot similar to the above and paste it to the Word document named lab12.doc (or .docx).

Submittal

1. Complete all the 5 learning activities.

2. Create a .zip file named lab12.zip containing ONLY the following self-executable files.

• Lab12_1.exe

Page 26: Lecture #12 LINQ Introduction LINQ is short for l in qstudents.cypresscollege.edu/cis218/lc12.pdf · Visual C# - Penn P. Wu, PhD. 380 Lecture #12 LINQ Introduction LINQ is short for

Visual C# - Penn P. Wu, PhD. 405

• Lab12_2.exe

• Lab12_3.exe

• Lab12_4.exe

• Lab12_5.exe

• Lab12.doc (or .docx) [You may be given zero point if this Word document is missing]

3. Log in to course site and enter the course site.

4. Upload the zipped file as response to question 11.

Programming Exercise:

1. Use Notepad to create a new file named ex12.cs with the following heading lines (be sure to replace

YourFullNameHere with the correct one):

//File Name: ex12.cs

//Programmer: YourFullNameHere

2. Add the following code to your source file. Then, use the InputBox.cs code to ask user to enter an integer. Let

the message be “How many bitcoins do you have?”. Write a proper LINQ code with at least one foreach

structure to process the elements of the List. In each iteration, be sure to calculate the value using the formular:

rate × numberOfBitcoin (where rate is the element of the list and numberOfBitcoin is the user input).

Additionally, use the LINQ Average() method to calculate the average rate and display it as the last line of the

output.

List<double> rate = new List<double>();

rate.Add(801.72);

rate.Add(823.61);

rate.Add(818.40);

rate.Add(819.54);

3. A sample output should look:

and

4. Download the “programming exercise template”, and rename it to ex12.doc. Capture a screen shot similar to the above figure and then paste it to the Word document named “ex12.doc” (or .docx).

5. Compress the source code (ex12.cs), the executable (ex12.exe), and the Word document (ex12.doc or .docx) to

a .zip file named “ex12.zip”. You may be given zero point if any of the required file is missing.

Grading Criteria:

• You must be the sole author of the codes.

• You must meet all the requirements in order to earn credits. You will receive zero if you use Visual Studio (C#)

IDE to generate the code.

• You must submit both source code (ex12.cs) and the executable (ex12.exe) to earn credit.

• No partial credit is given.