MSDN Documentation

Querying Data with LINQ to SQL

This section delves into the core functionality of LINQ to SQL: querying data from a relational database using Language Integrated Query (LINQ). LINQ to SQL provides a straightforward way to map database tables and views to .NET objects and to express queries against this data using familiar LINQ syntax.

Understanding the DataContext

The DataContext is the central class in LINQ to SQL. It represents a connection to the database and is responsible for managing objects, tracking changes, and executing queries. You typically create an instance of DataContext to interact with your database.

For example, assuming you have a database connection string and a mapping defined:


using System.Linq;
using YourNamespace.Database; // Assuming your generated DataContext resides here

public class DataQueryService
{
    private readonly YourDatabaseDataContext _db;

    public DataQueryService(string connectionString)
    {
        _db = new YourDatabaseDataContext(connectionString);
    }

    // ... query methods will go here
}
            

Basic Querying

LINQ to SQL allows you to write queries using method syntax or query syntax. Both translate to SQL at runtime.

Retrieving All Records

To retrieve all records from a table, you can access the corresponding Table<TEntity> property on your DataContext.


// Example: Get all customers
var allCustomers = _db.Customers.ToList();
            

Filtering Data (WHERE Clause)

The Where() extension method is used to filter data based on specified conditions, which translates to a SQL WHERE clause.


// Example: Get customers from London
var londonCustomers = _db.Customers.Where(c => c.City == "London").ToList();

// Using query syntax:
var londonCustomersQuery = from c in _db.Customers
                           where c.City == "London"
                           select c;
var londonCustomersList = londonCustomersQuery.ToList();
            

Sorting Data (ORDER BY Clause)

The OrderBy() and OrderByDescending() methods are used for sorting, mapping to SQL's ORDER BY clause.


// Example: Get customers sorted by name
var sortedCustomers = _db.Customers.OrderBy(c => c.CompanyName).ToList();

// Example: Get customers sorted by name in descending order
var sortedCustomersDesc = _db.Customers.OrderByDescending(c => c.CompanyName).ToList();
            

Selecting Specific Columns (SELECT Clause)

You can project query results into new object types or anonymous types using the Select() method.


// Example: Get only the names and cities of customers
var customerNamesAndCities = _db.Customers.Select(c => new { c.CompanyName, c.City }).ToList();

// Using query syntax:
var customerNamesAndCitiesQuery = from c in _db.Customers
                                  select new { c.CompanyName, c.City };
var customerNamesAndCitiesList = customerNamesAndCitiesQuery.ToList();
            

Joining Tables (JOIN Clause)

LINQ to SQL supports joining multiple tables using the Join() method or the join keyword in query syntax.


// Example: Get orders along with customer names
var ordersWithCustomerNames = _db.Orders.Join(
    _db.Customers,
    order => order.CustomerID,
    customer => customer.CustomerID,
    (order, customer) => new { OrderID = order.OrderID, CustomerName = customer.CompanyName, OrderDate = order.OrderDate }
).ToList();

// Using query syntax:
var ordersWithCustomerNamesQuery = from o in _db.Orders
                                   join c in _db.Customers on o.CustomerID equals c.CustomerID
                                   select new { OrderID = o.OrderID, CustomerName = c.CompanyName, OrderDate = o.OrderDate };
var ordersWithCustomerNamesList = ordersWithCustomerNamesQuery.ToList();
            

Grouping Data (GROUP BY Clause)

The GroupBy() method allows you to group data based on a specified key.


// Example: Group customers by city
var customersGroupedByCity = _db.Customers
    .GroupBy(c => c.City)
    .Select(g => new { City = g.Key, Count = g.Count() })
    .ToList();

// Using query syntax:
var customersGroupedByCityQuery = from c in _db.Customers
                                  group c by c.City into g
                                  select new { City = g.Key, Count = g.Count() };
var customersGroupedByCityList = customersGroupedByCityQuery.ToList();
            

Aggregation Functions

LINQ to SQL supports common aggregation functions like Count(), Sum(), Average(), Min(), and Max().


// Example: Count total orders
int totalOrders = _db.Orders.Count();

// Example: Calculate the total quantity of a specific product ordered
int productIdToCalculate = 1;
decimal totalQuantity = _db.OrderDetails
    .Where(od => od.ProductID == productIdToCalculate)
    .Sum(od => od.Quantity);

// Example: Find the highest unit price
decimal highestUnitPrice = _db.Products.Max(p => p.UnitPrice);
            
Important: LINQ to SQL defers query execution. When you call methods like ToList(), ToArray(), or iterate over the results, the actual SQL query is generated and sent to the database.

Lazy Loading and Eager Loading

LINQ to SQL supports lazy loading by default, where related data is fetched only when it's accessed. You can also explicitly configure eager loading for performance benefits in certain scenarios.

To enable eager loading, you can use the LoadWith option:


// Example: Eagerly load customers along with their orders
DataLoadOptions dlo = new DataLoadOptions();
dlo.LoadWith<Customer>(c => c.Orders); // Assuming 'Orders' is the navigation property
_db.LoadOptions = dlo;

var customersWithOrders = _db.Customers.ToList(); // Orders will be loaded here too
            
Consider the performance implications of eager loading. If you only need a few related items, lazy loading might be more efficient.

Summary

Querying data with LINQ to SQL offers a powerful and intuitive way to interact with your database. By leveraging LINQ, you can write concise, readable, and type-safe queries that are translated into efficient SQL statements.

This section covered:

Continue to the next section to explore data manipulation (inserting, updating, deleting) with LINQ to SQL.