ADO.NET Parameters

This document explores the fundamental role of parameters in ADO.NET for securely and efficiently interacting with databases.

Understanding Parameters

Parameters are essential for building robust database applications. They help prevent SQL injection vulnerabilities by separating SQL code from user-provided data. Additionally, parameters allow the database engine to cache query plans, leading to improved performance.

Why Use Parameters?

Types of Parameters

ADO.NET supports several ways to define parameters, primarily through the use of placeholders in your SQL commands:

Working with Parameters

The core class for managing parameters is DbParameter, which has provider-specific implementations like SqlParameter (for SQL Server) and OracleParameter (for Oracle).

Adding Parameters

You typically add parameters to a command's Parameters collection.

C# Example (SQL Server)


using System.Data.SqlClient;

// ...

using (SqlConnection connection = new SqlConnection(connectionString))
{
    connection.Open();
    string query = "SELECT CustomerName FROM Customers WHERE CustomerID = @ID";
    SqlCommand command = new SqlCommand(query, connection);

    // Add a named parameter
    command.Parameters.AddWithValue("@ID", customerId);

    // Or explicitly define parameter type and size
    // SqlParameter param = new SqlParameter("@ID", SqlDbType.Int);
    // param.Value = customerId;
    // command.Parameters.Add(param);

    // ... execute command ...
}
                

VB.NET Example (SQL Server)


Imports System.Data.SqlClient

' ...

Using connection As New SqlConnection(connectionString)
    connection.Open()
    Dim query As String = "SELECT CustomerName FROM Customers WHERE CustomerID = @ID"
    Dim command As New SqlCommand(query, connection)

    ' Add a named parameter
    command.Parameters.AddWithValue("@ID", customerId)

    ' Or explicitly define parameter type and size
    ' Dim param As New SqlParameter("@ID", SqlDbType.Int)
    ' param.Value = customerId
    ' command.Parameters.Add(param)

    ' ... execute command ...
End Using
                

Parameter Direction

Parameters can be used for input, output, or both. The Direction property of a DbParameter object controls this.

Note on Output Parameters

When using output parameters, you must specify a size for string-based parameters to correctly retrieve the returned value.

Parameter Types and Size

It's good practice to specify the DbType or the provider-specific type (e.g., SqlDbType) and size for parameters. This improves clarity and can help the database optimize operations.

Common Parameter Properties

Property Description
ParameterName The name of the parameter (e.g., "@CustomerID").
Value The value assigned to the parameter.
Direction Indicates whether the parameter is for input, output, or both.
DbType The data type of the parameter (e.g., DbType.Int32, DbType.String).
Size The maximum size of the parameter value for string types or variable-length data types.
SourceColumn The name of the source column in a DataTable.
SourceVersion Specifies the version of the column value to use (e.g., DataRowVersion.Current).

Example: Stored Procedure with Input and Output Parameters

Consider a stored procedure that updates a record and returns the number of rows affected.

SQL Stored Procedure (Conceptual)


CREATE PROCEDURE UpdateProductPrice
    @ProductID INT,
    @NewPrice DECIMAL(10, 2),
    @RowsAffected INT OUTPUT
AS
BEGIN
    UPDATE Products
    SET UnitPrice = @NewPrice
    WHERE ProductID = @ProductID;

    SET @RowsAffected = @@ROWCOUNT;
END
                

C# Code to Execute


using System.Data;
using System.Data.SqlClient;

// ...

using (SqlConnection connection = new SqlConnection(connectionString))
{
    connection.Open();
    SqlCommand command = new SqlCommand("UpdateProductPrice", connection);
    command.CommandType = CommandType.StoredProcedure;

    // Input parameter for ProductID
    command.Parameters.AddWithValue("@ProductID", 101);

    // Input parameter for NewPrice
    command.Parameters.AddWithValue("@NewPrice", 25.99);

    // Output parameter for RowsAffected
    SqlParameter outputParam = new SqlParameter("@RowsAffected", SqlDbType.Int);
    outputParam.Direction = ParameterDirection.Output;
    command.Parameters.Add(outputParam);

    command.ExecuteNonQuery();

    // Retrieve the output value
    int affectedCount = (int)outputParam.Value;
    Console.WriteLine($"Rows affected: {affectedCount}");
}
                

Tip: Use AddWithValue Wisely

While AddWithValue is convenient, it can sometimes lead to incorrect data type inference. For critical operations or when dealing with specific data types, it's often better to explicitly create and configure SqlParameter (or provider-specific) objects.

Parameter Discovery

Some data providers support parameter discovery, where ADO.NET can automatically retrieve the parameter information for a stored procedure from the database. This can be useful for dynamically building commands.


SqlCommandBuilder.DeriveParameters(command);
// Now the command.Parameters collection is populated.
        

Conclusion

Mastering ADO.NET parameters is crucial for writing secure, efficient, and maintainable data access code. By understanding the different types of parameters, their properties, and best practices, you can significantly improve the quality of your .NET database applications.