MSDN Documentation

Microsoft Developer Network

Data Access with SQL Server using ADO.NET

This document delves into the specifics of interacting with Microsoft SQL Server databases using the ADO.NET framework. ADO.NET provides a rich set of objects and classes designed to streamline data access operations.

Introduction to ADO.NET and SQL Server

ADO.NET is a set of managed code libraries that expose data access services to the .NET Framework. It allows developers to write applications that can access data from various data sources, including relational databases like SQL Server, NoSQL databases, and even flat files.

When working with SQL Server, ADO.NET offers specialized providers that optimize performance and leverage SQL Server-specific features. The primary provider for SQL Server is System.Data.SqlClient.

Key ADO.NET Objects for SQL Server

1. SqlConnection

The SqlConnection object represents a unique session to a SQL Server database. It is used to establish a connection, which is essential before executing any commands or retrieving data.

using System.Data.SqlClient;

// ...

string connectionString = "Server=myServerAddress;Database=myDataBase;User ID=myUsername;Password=myPassword;";
using (SqlConnection connection = new SqlConnection(connectionString))
{
    try
    {
        connection.Open();
        Console.WriteLine("Connection opened successfully!");
        // Proceed with data operations
    }
    catch (SqlException e)
    {
        Console.WriteLine("Error connecting to SQL Server: " + e.Message);
    }
}

2. SqlCommand

The SqlCommand object represents an SQL statement or stored procedure to be executed against a data source. It can be used to perform operations like querying data, inserting, updating, or deleting records.

using (SqlCommand command = new SqlCommand("SELECT COUNT(*) FROM Employees", connection))
{
    int count = (int)command.ExecuteScalar();
    Console.WriteLine($"Number of employees: {count}");
}

3. SqlDataReader

The SqlDataReader provides a way to retrieve a forward-only stream of rows from a SQL Server database. It's highly efficient for reading large amounts of data because it reads data row by row, without buffering the entire result set in memory.

using (SqlCommand command = new SqlCommand("SELECT EmployeeID, FirstName, LastName FROM Employees", connection))
{
    using (SqlDataReader reader = command.ExecuteReader())
    {
        while (reader.Read())
        {
            Console.WriteLine($"ID: {reader["EmployeeID"]}, Name: {reader["FirstName"]} {reader["LastName"]}");
        }
    }
}

4. SqlDataAdapter and DataSet

For scenarios where you need to work with data disconnected from the database (e.g., manipulating data in memory and then updating the database), SqlDataAdapter and DataSet are invaluable. SqlDataAdapter acts as a bridge between a DataSet and a SQL Server data source, managing the retrieval and saving of data.

string query = "SELECT CustomerID, CompanyName FROM Customers";
using (SqlDataAdapter adapter = new SqlDataAdapter(query, connection))
{
    DataSet dataSet = new DataSet();
    adapter.Fill(dataSet, "Customers"); // Fills the DataSet with data

    // Manipulate data in the DataSet
    DataTable customerTable = dataSet.Tables["Customers"];
    foreach (DataRow row in customerTable.Rows)
    {
        Console.WriteLine($"{row["CustomerID"]} - {row["CompanyName"]}");
    }

    // To update the database (requires SqlCommandBuilder or explicit UPDATE commands)
    // SqlCommandBuilder commandBuilder = new SqlCommandBuilder(adapter);
    // adapter.Update(dataSet, "Customers");
}

Best Practices for SQL Server Data Access

Security Note:

Never hardcode connection strings directly in your code. Use configuration files (like appsettings.json or Web.config) or secure secret management solutions.

By understanding and utilizing these ADO.NET components, developers can efficiently and securely build robust applications that interact with SQL Server databases.