In this article
You will get to know about...Introduction :
In the realm of C# development, managing and extracting data from Data sources like DataTables etc. is a common task. However, traditional approaches to data retrieval can often be cumbersome and verbose. Enter LINQ ( Language Integrated Query ), a powerful feature of C# that revolutionizes the way we work with collections and data sources.
In this blog post, we'll explore how LINQ simplifies data extraction from data sources, focusing on a specific scenario: retrieving the data from the data sources based on the real life scenarios. We'll delve into a concise LINQ query that elegantly handles this task, demonstrating the efficiency and readability that LINQ brings to C# development.
Join us as we unlock the potential of LINQ to streamline data manipulation, making our code more expressive and our development process more efficient. Let's dive in!
What is a query and what does it do? 🤔💭
Think of the data source as a big box of assorted items. In a database, it's like looking through rows of neatly stacked items. In an XML file, it's more like sifting through a stack of pages, each with different bits of information. And in an in-memory collection, it's as if you're sorting through a pile of objects, each with its own unique details.
But here's the thing: the query itself isn't the stuff you're looking for. It's more like the map 🗺️ that guides you to the treasure. It tells you where to look and how to organize what you find.
So, a query helps you find what you need from a bunch of data, kind of like asking for directions to a hidden treasure. 🕵️♂️💎
Language Integrated Query (LINQ)
Traditionally, queries against data are expressed as simple strings without type checking at compile time or IntelliSense support.
Furthermore, you'd typically have to become fluent in a different query language for each type of data source: SQL databases, XML documents, various Web services, and so on. 📊📜🌐 But with LINQ, it's like having a universal translator built right into your C# toolkit. 🚀 No need to juggle multiple languages – LINQ empowers you to speak the language of data, no matter where it resides. 🗣💻
The following example shows a complete query operation. The complete operation includes creating a data source, defining the query expression, and executing the query in a foreach statement. 👇
// Data source: array of scores
int[] scores = { 97, 92, 81, 60 };
// Query to select scores greater than 80
var scoreQuery = from score in scores
where score > 80
select score;
// Execution of the query and output
foreach (var score in scoreQuery)
{
Console.Write(score + " ");
}
// Output: 97 92 81
In this code : 👆
→ We utilize LINQ's where clause to filter scores greater than 80.
→ The query expression score > 80 acts as the condition to filter the scores.
→ Finally, we retrieve and process the filtered scores using a foreach loop.
Three Parts of a Query Operation
1. Obtain the data source.
2. Create the query.
3. Execute the query.
// Let's Explore LINQ in Three Steps:
// Step 1: Setting Up the Numbers
// Imagine a bunch of numbers waiting for us to dig into.
int[] numbers = { 0, 1, 2, 3, 4, 5, 6 };
// Step 2: Crafting Our Search
// We're looking for certain numbers here - the even ones.
// 'numQuery' will help us find them.
var numQuery = from num in numbers
where (num % 2) == 0
select num;
// Step 3: Finding and Displaying
// Time to see what we've found!
// We'll loop through the results and print them out.
foreach (int num in numQuery)
{
Console.Write("{0,1} ", num);
}
→ "{0,1}" : This is a format string. The {0} indicates where to insert the value of the variable num. The ,1 specifies the minimum field width as 1 character.
Data Source Overview
| CustomerId | Name | City | |------------|----------|---------| | 1 | John | London | | 2 | Alice | Paris | | 3 | Bob | London | | 4 | Emma | New York| | 5 | Michael | London |
// Query to Retrieve Customers in London
IQueryable<Customer> customersInLondonQuery = from customer in database.Customers
where customer.City == "London"
select customer;
In this code : 👆
→ In the following example, Customers represents a specific table in the database, and the type of the query result, IQueryable
Forcing Immediate Execution
Queries that perform aggregation functions, like Count, Max, Average, and First, need to iterate over the source elements to compute their result. These queries return a single value rather than a collection. For example, the following query counts the even numbers in the source array.
// Sample array of numbers
int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
// Query to Count Even Numbers
var evenNumberQuery = from number in numbers
where (number % 2) == 0
select number;
// Counting Even Numbers
int evenNumberCount = evenNumberQuery.Count();
→ To force immediate execution of any query and cache its results, you can call the ToList or ToArray methods.
→ These methods compel the query to be executed instantly, storing the results in a list or array, respectively.
→ This can be particularly useful when you need to manipulate or iterate over the results multiple times without re-executing the query.
// Immediate Execution with ToList()
List<int> evenNumbersList = (from num in numbers
where (num % 2) == 0
select num).ToList();
// Immediate Execution with ToArray()
int[] evenNumbersArray = (from num in numbers
where (num % 2) == 0
select num).ToArray();
In these queries : 👆
→ We're using LINQ to filter even numbers from the numbers array.
→ The ToList() and ToArray() methods ensure immediate execution of the query and cache the results in a list or array, respectively.
You can also enforce query execution by immediately following the query expression with a foreach loop. However, utilizing ToList or ToArray not only triggers execution but also caches all the data within a single collection object. This can be advantageous when you need to reuse or manipulate the results multiple times efficiently.
Given this source sequence, a query might do one of three things : 👇
→ Retrieve a subset of the elements to produce a new sequence without modifying the individual elements.
// LINQ query to filter and sort high scores
IEnumerable highScoresQuery = from score in scores
where score > 80
orderby score descending
select score;
→ Retrieve a sequence of elements as in the previous example but transform them to a new type of object. The following example shows a projection from an int to a string. Note the new type of highScoresQuery.
// LINQ query to filter and format high scores
IEnumerable highScoresQuery2 = from score in scores
where score > 80
orderby score descending
select $"The score is {score}";
→ Retrieve a singleton value about the source data
// Counting high scores above 80
var highScoreCount = (from score in scores
where score > 80
select score).Count();
Starting a query expression 👇
→ Query expressions in C# begin with a "from" clause, defining a data source and a range variable.
→ The range variable iterates over each element in the source sequence during traversal.
→ The "from" clause specifies the data source and introduces a range variable.
→ The range variable is strongly typed according to the elements in the data source.
→ For instance, if the data source is an array of Country objects, the range variable is also typed as Country.
| CountryId | Name | Population | |-----------|-------------|------------| | 1 | USA | 10000 | | 2 | China | 5000 | | 3 | India | 10000 | | 4 | Brazil | 20000 | | 5 | Pakistan | 50000 | | ... | ... | ... |
// Query to filter countries with a population greater than 10 thousand and select their names
var query = from country in countries
where country.Population > 10000
select country.Name;
A query expression might contain multiple from clauses. Use more from clauses when each element in the source sequence is itself a collection or contains a collection. For example, assume that you have a collection of Country objects, each of which contains a collection of City objects named Cities. To query the City objects in each Country, use two from clauses as shown here:
IEnumerable<City> cityQuery = from country in countries
from city in country.Cities
where city.Population > 10000
select city;
Ending a query expression 👇
A query expression must end with either a group clause or a select clause.
→ group clause
0 Comments