# C# Expression
LinqPad expression queries return the results from evaluating the LINQ query.
# Select All
The simplest way to get all the rows of a table is to just reference the table. In this case, there is no LINQ being used at all.
Categories
The equivalent code using LINQ to get all the rows looks like this.
from kind in Categories
select kind
If the above statement was written using method syntax, it would look like this.
Categories
.Select (kind => kind)
# Simple Where Clause
Results from a select can be filtered by using a where clause, as in this example that checks the value in a given column.
from row in Products
where row.UnitPrice > 50
select row
This is also a good time to check out the output window on LinqPad to compare the Results, λ (method syntax) and SQL for the LINQ expression entered.
// λ - Method syntax
Products
.Where (row => (row.UnitPrice > (Decimal?)((Decimal)50)))
Remember that in this sample, row
is merely a variable name; we could have named it anything we wanted.
Observe that the header of the results identifies the data type of the collection: IOrderedQueryable<Products>
. Depending on the code you write in the LinqPad editor, the results could be a generic kind that is evaluated by generating SQL (one of the IQueryable
types) or producing an in-memory result (IEnumerable
) or even a strongly-typed result (as in one of the examples on the bottom of the page). Also notice that in LinqPad, the Results window shows a column for the Category
, Supplier
and OrderDetails
. Clicking on those will bring up the information in the related tables that corresponds with the specific product in that row.
If you have experience in working with databases, you may be tempted to start "thinking in SQL", particularly when you see keywords such as from
, where
and select
. LINQ, however, is Language INtegrated Queries, meaning that the code you are writing is actually part of the C# (or VB) syntax. Keep that in mind, particularly as you look at writing the conditional expression in your where
clauses.
from item in Products
where item.ProductName.StartsWith("Chef")
select item
TIP
Remember - LINQ is still C#, so expressing a boolean expression in the where clause is written as C# (not SQL).
Notice that the method syntax makes uses of Lambda expressions. Lambdas are common when performing LINQ with the Method syntax.
Products
.Where (item => item.ProductName.StartsWith("Chef"))
TIP
Here is another sample looking for Customers in a particular region:
from company in Customers
where company.Region.Equals("BC")
select company
Note that in this example, we are using the .Equals()
method of the string class, rather than the equal-to sign ==
. The reason for this is that the Region
column can contain NULL
values. Using the .Equals()
avoids the problem of possible database NULL
values causing a run-time error. Whenever a string column states it can hold NULL
values, use the .Equals()
when comparing values in your where clause.
Just to drive home the point, see this example that uses the C# !
operator. Also note that the column it is checking allows NULL
values, and in C# this is being represented as a nullable data type.
from sale in Orders
where !sale.ShippedDate.HasValue
select sale
# Try this
- In the LinqPad example above, when you click on the
Customer
andOrderDetails
, what does that tell you about the relationship between these and theOrders
data?
# Simple OrderBy
By default, sorting is done in ascending order.
from row in Shippers
orderby row.CompanyName
select row
// λ - Method Syntax
Shippers
.OrderBy(row => row.CompanyName)
You can specify the descending and ascending order explicitly.
from row in Shippers
orderby row.CompanyName descending
select row
// λ - Method Syntax
Shippers
.OrderByDescending(row => row.CompanyName)
from item in Products
orderby item.UnitPrice ascending
select item
// λ - Method Syntax
Products
.OrderBy (item => item.UnitPrice)
You can sort by multiple columns.
from item in Products
orderby item.UnitPrice ascending, item.ReorderLevel descending
select item
// λ - Method Syntax
Products
.OrderBy (item => item.UnitPrice)
.ThenByDescending (item => item.ReorderLevel)
# Grouping
Grouping can be used as a result in itself, without the select
clause. Grouping produces a result that has two parts: a Key value, and the grouped items.
from item in Products
group item by item.SupplierID
// λ - Method Syntax
Products
.GroupBy (item => item.SupplierID)
Like ordering, grouping can include more than one column. All you have to do is use an anonymous type for your grouping condition.
from item in Products
group item by new {item.SupplierID, item.CategoryID}
Notice the use of new {item.SupplierID, item.CategoryID}
. This is an example of anonymous types (used in the grouping clause). You will read more about anonymous types in the result set of the select later on.
// λ - Method Syntax
Products
.GroupBy (
item =>
new
{
SupplierID = item.SupplierID,
CategoryID = item.CategoryID
}
)
A group can become something from which you can select your actual data. All you have to do is give a name to the resulting group.
from item in Products
group item by item.SupplierID into result
select result
// λ - Method Syntax
Products
.GroupBy (item => item.SupplierID)
.Select (result => result)