Introduction to LINQ
LINQ (Language Integrated Query) lets you write strongly typed queries directly in VB.NET against in-memory collections, XML, or databases, using a syntax that resembles SQL but is checked by the compiler. Any type implementing IEnumerable(Of T) can be queried with LINQ, and the result is itself typically an IEnumerable(Of T), which means LINQ queries can be composed and chained. VB.NET supports both query syntax (From...Where...Select) and method syntax (.Where().Select()), which compile down to the same underlying method calls.
Cricket analogy: LINQ working over any IEnumerable is like a scoring analyst who can run the same statistical query — say, filtering for sixes hit off spin bowling — against any team's match data, whether it's IPL or Test cricket.
Query Syntax
Dim numbers = New List(Of Integer) From {4, 8, 15, 16, 23, 42}
Dim evenSquares = From n In numbers
Where n Mod 2 = 0
Order By n Descending
Select n * n
For Each sq In evenSquares
Console.WriteLine(sq)
NextVB.NET's query syntax reads close to SQL: From introduces a range variable over a source sequence, Where filters elements, Order By sorts (ascending by default, Descending to reverse), and Select projects each element into a new shape. Because Select can construct anonymous types with New With {...}, you can reshape data — for example pulling just a couple of fields from a larger object — without defining a separate class.
Cricket analogy: A Where clause filtering n Mod 2 = 0 is like a selector shortlisting only players with a strike rate above 140 from the full squad list before finalizing the playing XI.
Method Syntax and Lambda Expressions
Method syntax expresses the same operations as extension methods with lambda expressions: numbers.Where(Function(n) n Mod 2 = 0).OrderByDescending(Function(n) n).Select(Function(n) n * n). Lambdas written with the Function keyword are anonymous, inline functions that capture variables from the enclosing scope, and they are what LINQ's extension methods — defined in System.Linq.Enumerable — actually accept as arguments; query syntax is compiler sugar that gets translated into these same method calls.
Cricket analogy: A lambda like Function(n) n Mod 2 = 0 is like a one-line instruction to a fielding coach: 'keep only bowlers who took 3 or more wickets' — compact, inline criteria rather than a whole separate rulebook.
LINQ queries over IEnumerable(Of T) use deferred execution: the query itself is not run when you write it, only when you actually enumerate it (with For Each, ToList(), or similar). This means the query can pick up changes to the underlying source made between definition and enumeration, and it lets you build up complex queries without incurring repeated evaluation cost until the results are actually needed.
LINQ to Objects vs LINQ to SQL/Entities
LINQ to Objects executes entirely in memory against IEnumerable(Of T) sources like List(Of T) or arrays, running your lambda bodies directly as VB.NET code. LINQ to Entities (via Entity Framework) and LINQ to SQL instead work against IQueryable(Of T), where the same query syntax is translated into an expression tree and converted into actual SQL sent to the database, so only matching rows are ever transferred over the network rather than the entire table being pulled into memory first.
Cricket analogy: LINQ to Objects filtering in-memory data is like a commentator flipping through a printed scorecard in the booth, while LINQ to Entities is like radioing the ground staff to fetch only the specific over's details from the archive.
Calling ToList() or enumerating a deferred LINQ query multiple times re-executes it each time, which can silently run an expensive database query — or even produce inconsistent results if the source data changed between enumerations. If you need the results more than once, materialize them once with .ToList() or .ToArray() and reuse that collection.
Aggregate Operations
LINQ provides aggregate extension methods — Count(), Sum(), Average(), Min(), Max(), and the more general Aggregate() — that collapse a sequence into a single value. Count and Sum can take an optional predicate or selector lambda, so numbers.Count(Function(n) n > 10) counts only elements matching the condition without a separate Where call, and the generic Aggregate method lets you fold a sequence with a custom accumulator function for logic none of the built-in aggregates cover.
Cricket analogy: Sum() totaling a sequence is like a scorer adding up every run scored across an entire innings into one final total displayed on the board.
- LINQ lets you query any IEnumerable(Of T) using SQL-like query syntax or chained method syntax with lambdas.
- Query syntax and method syntax compile down to the same Enumerable extension method calls.
- LINQ queries use deferred execution — they don't run until enumerated with For Each, ToList, or similar.
- LINQ to Objects runs in memory; LINQ to Entities/SQL translates queries into IQueryable expression trees executed as SQL.
- Materialize a query once with ToList() if you need to reuse the results without re-executing it.
- Aggregate methods like Sum, Count, Average, and the general Aggregate() collapse a sequence into a single value.
- Anonymous types created with New With let Select project just the fields you need.
Practice what you learned
1. What does the following compile down to: From n In numbers Where n > 5 Select n?
2. What does deferred execution mean for a LINQ query?
3. What is the key difference between LINQ to Objects and LINQ to Entities?
4. What does numbers.Count(Function(n) n > 10) do?
5. Why might repeatedly enumerating the same unmaterialized LINQ query be a problem?
Was this page helpful?
You May Also Like
ADO.NET and Database Access
Learn how VB.NET applications connect to relational databases using ADO.NET's connection, command, and reader objects, plus disconnected DataSets and transactions.
Async/Await in VB.NET
Learn how the Async and Await keywords let VB.NET applications perform non-blocking I/O and long-running work without freezing the UI or wasting threads.
Events and Delegates in VB.NET
Understand how delegates provide type-safe function references in VB.NET, and how the Event/RaiseEvent/WithEvents system builds the observer pattern on top of them.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics