MSDN Documentation

Data Access Objects in ADO.NET

This document provides an in-depth overview of Data Access Objects (DAOs) within the ADO.NET framework, a foundational technology for data access in .NET applications. DAOs represent a design pattern that abstracts the underlying data access logic, making your application more maintainable, testable, and flexible.

Introduction to Data Access Objects

The Data Access Object (DAO) pattern is a structural design pattern that isolates the data access logic from the rest of the application. Instead of scattering database queries and connection management throughout your codebase, you encapsulate them within dedicated DAO classes. This approach offers several benefits:

Core ADO.NET Objects for Data Access

ADO.NET provides a rich set of objects that form the building blocks for implementing the DAO pattern. The most crucial ones include:

Implementing a Simple DAO

Let's consider a simple example of a DAO for managing Product entities. We'll use the SqlClient provider for SQL Server.

1. Define the Entity Class

First, define the class that represents our data:

public class Product
{
    public int ProductId { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
}

2. Create the Product DAO Class

Next, create a class responsible for interacting with the database for Product objects.

using System;
using System.Collections.Generic;
using System.Data.SqlClient; // Or other provider namespace

public class ProductDao
{
    private readonly string _connectionString;

    public ProductDao(string connectionString)
    {
        _connectionString = connectionString ?? throw new ArgumentNullException(nameof(connectionString));
    }

    public Product GetProductById(int productId)
    {
        Product product = null;
        using (SqlConnection connection = new SqlConnection(_connectionString))
        {
            string sql = "SELECT ProductId, Name, Price FROM Products WHERE ProductId = @ProductId";
            using (SqlCommand command = new SqlCommand(sql, connection))
            {
                command.Parameters.AddWithValue("@ProductId", productId);
                connection.Open();
                using (SqlDataReader reader = command.ExecuteReader())
                {
                    if (reader.Read())
                    {
                        product = new Product
                        {
                            ProductId = reader.GetInt32(0),
                            Name = reader.GetString(1),
                            Price = reader.GetDecimal(2)
                        };
                    }
                }
            }
        }
        return product;
    }

    public IEnumerable<Product> GetAllProducts()
    {
        var products = new List<Product>();
        using (SqlConnection connection = new SqlConnection(_connectionString))
        {
            string sql = "SELECT ProductId, Name, Price FROM Products";
            using (SqlCommand command = new SqlCommand(sql, connection))
            {
                connection.Open();
                using (SqlDataReader reader = command.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        products.Add(new Product
                        {
                            ProductId = reader.GetInt32(0),
                            Name = reader.GetString(1),
                            Price = reader.GetDecimal(2)
                        });
                    }
                }
            }
        }
        return products;
    }

    public void AddProduct(Product product)
    {
        using (SqlConnection connection = new SqlConnection(_connectionString))
        {
            string sql = "INSERT INTO Products (Name, Price) VALUES (@Name, @Price)";
            using (SqlCommand command = new SqlCommand(sql, connection))
            {
                command.Parameters.AddWithValue("@Name", product.Name);
                command.Parameters.AddWithValue("@Price", product.Price);
                connection.Open();
                command.ExecuteNonQuery();
            }
        }
    }
}

Key Considerations for DAO Implementation

ADO.NET Data Providers

ADO.NET supports various data providers, each designed to connect to a specific data source. Common providers include:

The core ADO.NET objects (Connection, Command, etc.) have provider-specific implementations (e.g., SqlConnection, SqlCommand). Your DAO implementation will typically depend on a specific provider.