HomeSearch

VB.NET LINQ Examples: Queries, Extensions

Use LINQ, a set of extensions to the language that enable queries.
LINQ. This stands for Language Integrated Query. We import the System.Linq namespace. This provides many extension methods, ones that act on collections.
It allows queries. In a query expression, we describe a command in terms of the desired result. So we can say "get all items greater than 10" rather than use a loop.
A query. This example uses a query expression. The "result" Dim is assigned to a query's result: it uses a special syntax form. It examines all array elements, naming each "v."

Where: It then uses the Where keyword to filter elements. It only accepts elements greater than or equal to 10.

So: When we evaluate the "result" value in our For-Each loop, we see only the elements that the query selected. These are 10 and 100.

For Each, For
VB.NET program that uses query Imports System.Linq Module Module1 Sub Main() ' An array of 4 elements. Dim values() As Integer = {1, 10, 100, 5} ' Gets all values greater than 9. Dim result = From v In values Where v >= 10 ' Display all matching Integers. For Each value As Integer In result Console.WriteLine(value) Next End Sub End Module Output 10 100
Order By. With Order By we can sort the results of a query. This statement comes after other query clauses like "Where." By default it is Ascending, ordering from low to high.
VB.NET program that uses Order By Imports System.Linq Module Module1 Sub Main() Dim values() As Integer = {3, 10, -1, 30, -3} ' Order the elements from low to high (ascending). Dim result = From v In values Order By v For Each value As Integer In result Console.WriteLine(value) Next End Sub End Module Output -3 -1 3 10 30
Descending. We can apply the Descending keyword to an Order By clause in a query expression. This orders the elements from last to first (for strings, "Z" to "A").

Tip: For numbers, Descending orders from largest to smallest. Strings use a reverse alphabetical sort.

VB.NET program that uses order by, descending Imports System.Linq Module Module1 Sub Main() Dim animals() As String = {"cat", "turtle", "ant"} ' Sort animals alphabetically, last to first. Dim result = From a In animals Order By a Descending For Each value As String In result Console.WriteLine(value) Next End Sub End Module Output turtle cat ant
Group By, Into. With a query, we can also group elements together into automatically-generated groups. The syntax is confusing. We use the "Group" keyword twice—once for naming the group.

By: After By, we specify the property that will be used to separate groups (here I use Item1, part of the tuples).

Tuple

Into: In this part of the Group clause, we assign an identifier to the group—it can be any valid identifier (I use "TupleGroup").

TupleGroup: Each group contains a collection called TupleGroup (named in the program). We loop over it to display all values.

VB.NET program that uses Group, By, Into Module Module1 Sub Main() ' Create list of tuples with two items each. Dim list = New List(Of Tuple(Of Integer, String)) list.Add(New Tuple(Of Integer, String)(5, "green")) list.Add(New Tuple(Of Integer, String)(5, "blue")) list.Add(New Tuple(Of Integer, String)(20, "orange")) list.Add(New Tuple(Of Integer, String)(20, "yellow")) list.Add(New Tuple(Of Integer, String)(20, "magenta")) ' Group tuples by their first item. ' ... TupleGroup is an identifier name. Dim result = From v In list Group v By v.Item1 Into TupleGroup = Group ' Loop over each group and its items. For Each value In result Console.WriteLine(value.Item1) For Each item In value.TupleGroup Console.WriteLine(" " + item.Item2) Next Next End Sub End Module Output 5 green blue 20 orange yellow magenta
Extensions. The System.Linq namespace also gives us many extension methods. In VB.NET we do not need to import the System.Linq namespace to use these extensions.Extension Method

Tip: These extensions, like Average(), act upon any collection of type IEnumerable. An array, List, or query result qualifies.

ArrayListIEnumerable

Here: We use Average to compute the average number in an array of four Integers. The average, a Double, happens to equal 5.

VB.NET program that uses average extension Module Module1 Sub Main() Dim numbers() As Integer = {2, 4, 6, 8} ' Use the Average extension from System.Linq. Dim average As Double = numbers.Average() Console.WriteLine(average) End Sub End Module Output 5
Chain extensions. Extension methods, like those found in LINQ, often return the results of their invocation. So we can call further extensions on them.

Here: Take() returns the first three elements, in an IEnumerable collection. So Average() can be invoked on its result.

VB.NET program that chains extension methods Module Module1 Sub Main() Dim elements() As Integer = {5, 10, 15, 20, 25} ' Take first 3 numbers and average them. Dim averageFirstThree = elements.Take(3).Average() Console.WriteLine(averageFirstThree) End Sub End Module Output 10
Any extension, lambda. The Any method returns True if the condition evaluates to True for any element in a sequence. This extension method can be used with a lambda expression.LambdaFunc, Action, Predicate
VB.NET program that uses Any, Func Module Module1 Sub Main() Dim values() As Integer = {10, -200, 1, 30, -1} ' See if the array has a negative number. Dim hasNegative = values.Any(Function(x As Integer) Return x < 0 End Function) Console.WriteLine(hasNegative) End Sub End Module Output True
Query and extension call. We can combine query syntax with extension method calls. Consider this example—it orders the numbers with a query expression (Order By).

Then: It uses the Take() extension upon the result of the query expression. This style is sometimes useful.

VB.NET program that uses query, extension method Imports System.Linq Module Module1 Sub Main() Dim numbers() As Integer = {5, 10, 1} ' Take first two numbers from ordered query. Dim result = (From n In numbers Order By n).Take(2) For Each value As Integer In result Console.WriteLine(value) Next End Sub End Module Output 1 5
FirstOrDefault. This is a useful LINQ extension method—it can help in many VB.NET programs. We call it on an IEnumerable instance. It has 2 possible results.

Result 1: If there is a first element in the collection (it has 1 or more elements), that value is returned by FirstOrDefault.

Result 2: If no first element exists (it has 0 elements total) the default value is returned. For int, this means we get a 0.

VB.NET program that uses FirstOrDefault Module Module1 Sub Main() Dim elements() As Integer = {5, 10, 15, 20, 25} ' Get first element safely. Dim first1 = elements.FirstOrDefault() Console.WriteLine("FIRSTORDEFAULT: {0}", first1) elements = {} ' If no first element is present, we get the default value 0. Dim first2 = elements.FirstOrDefault() Console.WriteLine("FIRSTORDEFAULT: {0}", first2) End Sub End Module Output FIRSTORDEFAULT: 5 FIRSTORDEFAULT: 0
ElementAtOrDefault. Here we use the ElementAt and ElementAtOrDefault functions. Most developers will find ElementAtOrDefault to be the more useful form.

Info: We call ElementAtOrDefault twice. If the index is in the range of the collection, it returns the string at that index.

And: If the index if out-of-range, it returns the default value, which for a string is null (which is not displayed).

ElementAt: This is the same as ElementAtOrDefault but will throw an exception if we pass an index that is not within the collection's size.

VB.NET program that uses ElementAt, ElementAtOrDefault Module Module1 Sub Main() Dim sizes = {"small", "medium", "large"} ' Use the safe ElementAtOrDefault function. Dim element1 = sizes.ElementAtOrDefault(1) Console.WriteLine("ELEMENTATORDEFAULT: {0}", element1) Dim element100 = sizes.ElementAtOrDefault(100) Console.WriteLine("ELEMENTATORDEFAULT: {0}", element100) ' Use ElementAt, which may throw an exception if out-of-range. Dim element2 = sizes.ElementAt(2) Console.WriteLine("ELEMENTAT: {0}", element2) End Sub End Module Output ELEMENTATORDEFAULT: medium ELEMENTATORDEFAULT: ELEMENTAT: large
ToArray, ToList. Some extension methods from System.Linq convert collections. With ToArray and ToList, we convert from an IEnumerable to an array or List. Many types implement IEnumerable.ToArrayToList
System.Xml.Linq. The System.Xml.Linq namespace contains the XElement type. With XElement we can load XML, even from the network, and query it with LINQ.XElement
Useful. Many VB.NET programs need no LINQ features: query expressions and extensions are not always useful. But these features have power. They make some programs shorter, easier to read.
Performance. Often LINQ features do not lead to the best performance. Using iterative statements, like for loops, and maintaining state in local variables is often faster.
© 2007-2019 Sam Allen. Every person is special and unique. Send bug reports to info@dotnetperls.com.
Home
Dot Net Perls