1. 认识System.Data.SqlClient技术栈

System.Data.SqlClient是.NET Framework中专门用于连接SQL Server数据库的核心组件(也支持.NET Core的Microsoft.Data.SqlClient)。它提供了ADO.NET接口的具体实现,能直接执行SQL命令、管理数据库连接和事务,特别适合需要精细控制数据库操作的场景。

技术特点

  • 原生支持T-SQL语法
  • 支持同步/异步操作
  • 完善的连接池管理
  • 参数化查询防注入机制

2. 建立数据库连接基础

// 连接字符串配置示例(请替换实际参数)
const string connectionString = "Server=你的服务器;Database=你的数据库;User Id=用户名;Password=密码;";

using (SqlConnection connection = new SqlConnection(connectionString))
{
    try
    {
        connection.Open();
        Console.WriteLine("数据库连接成功!");
        
        // 后续操作代码...
    }
    catch (SqlException ex)
    {
        Console.WriteLine($"连接错误:{ex.Number} - {ex.Message}");
    }
}

注意事项

  • 使用using语句确保连接自动关闭
  • 敏感信息建议通过ConfigurationManager配置
  • 生产环境建议启用Encrypt=True加密连接

3. 数据排序实战技巧

3.1 基础排序实现

public void SortProducts(string sortColumn = "Price", bool isDescending = false)
{
    using (SqlConnection conn = new SqlConnection(connectionString))
    {
        string orderDirection = isDescending ? "DESC" : "ASC";
        
        // 使用参数化排序字段(需验证列名合法性)
        string query = $@"SELECT ProductID, ProductName, Price 
                        FROM Products 
                        ORDER BY [{sortColumn}] {orderDirection}";

        SqlCommand cmd = new SqlCommand(query, conn);
        
        conn.Open();
        using (SqlDataReader reader = cmd.ExecuteReader())
        {
            while (reader.Read())
            {
                Console.WriteLine($"{reader["ProductID"]} | {reader["ProductName"]} | {reader["Price"]}");
            }
        }
    }
}

3.2 多字段动态排序

public void MultiFieldSort(List<Tuple<string, bool>> sortRules)
{
    // 构建排序子句
    var orderClauses = sortRules.Select(rule => 
        $"[{rule.Item1}] {(rule.Item2 ? "DESC" : "ASC")}");
    
    string orderBy = string.Join(", ", orderClauses);

    string query = $"SELECT * FROM SalesData ORDER BY {orderBy}";
    
    // 执行查询...
}

4. 数据筛选高级应用

4.1 基础筛选示例

public List<Product> FilterProducts(decimal minPrice, DateTime startDate)
{
    var products = new List<Product>();
    
    using (var conn = new SqlConnection(connectionString))
    {
        // 使用参数化查询防止SQL注入
        string query = @"SELECT * FROM Products 
                       WHERE Price > @MinPrice 
                         AND CreatedDate >= @StartDate";
        
        SqlCommand cmd = new SqlCommand(query, conn);
        cmd.Parameters.AddWithValue("@MinPrice", minPrice);
        cmd.Parameters.AddWithValue("@StartDate", startDate);

        conn.Open();
        using (var reader = cmd.ExecuteReader())
        {
            while (reader.Read())
            {
                products.Add(new Product
                {
                    ID = (int)reader["ProductID"],
                    Name = reader["ProductName"].ToString(),
                    Price = (decimal)reader["Price"]
                });
            }
        }
    }
    return products;
}

4.2 动态条件构建

public void DynamicFilter(Dictionary<string, object> filters)
{
    var whereClauses = new List<string>();
    var parameters = new List<SqlParameter>();

    int paramIndex = 0;
    foreach (var filter in filters)
    {
        string paramName = $"@p{paramIndex++}";
        whereClauses.Add($"[{filter.Key}] = {paramName}");
        parameters.Add(new SqlParameter(paramName, filter.Value));
    }

    string whereClause = whereClauses.Any() ? $"WHERE {string.Join(" AND ", whereClauses)}" : "";
    
    string query = $"SELECT * FROM Customers {whereClause}";
    
    using (var cmd = new SqlCommand(query, conn))
    {
        cmd.Parameters.AddRange(parameters.ToArray());
        // 执行查询...
    }
}

5. 组合应用:分页查询

public void PaginationQuery(int pageSize, int pageNumber, string sortField)
{
    string query = @"
        SELECT * 
        FROM (
            SELECT ROW_NUMBER() OVER (ORDER BY @SortField) AS RowNum, *
            FROM Products
        ) AS PagedResults
        WHERE RowNum BETWEEN @StartRow AND @EndRow";
    
    using (var cmd = new SqlCommand(query, conn))
    {
        int startRow = (pageNumber - 1) * pageSize + 1;
        int endRow = pageNumber * pageSize;
        
        cmd.Parameters.AddWithValue("@SortField", sortField);
        cmd.Parameters.AddWithValue("@StartRow", startRow);
        cmd.Parameters.AddWithValue("@EndRow", endRow);
        
        // 执行分页查询...
    }
}

6. 技术方案对比分析

6.1 应用场景

  • 适合场景:

    • 需要直接控制SQL语句
    • 处理复杂查询逻辑
    • 大数据量操作
    • 需要存储过程支持
  • 不适合场景:

    • 简单CRUD操作
    • 需要快速开发的项目
    • 多数据库支持需求

6.2 优缺点分析

优势

  1. 直接执行原生SQL,性能优化空间大
  2. 完全控制数据库交互过程
  3. 支持所有SQL Server特性
  4. 内存占用更少

劣势

  1. 需要手动编写大量SQL
  2. 缺乏强类型支持
  3. 需要自行管理对象映射
  4. 错误处理代码较多

7. 开发注意事项

7.1 安全规范

  • 必须使用参数化查询
  • 验证动态字段名称合法性
  • 禁止拼接SQL字符串
  • 合理设置命令超时时间

7.2 性能优化

  • 使用异步方法(BeginExecuteReader)
  • 合理配置连接池参数
  • 批量操作使用SqlBulkCopy
  • 及时释放数据库资源

7.3 异常处理

try
{
    // 数据库操作代码
}
catch (SqlException ex) when (ex.Number == 547)
{
    // 处理外键约束错误
}
catch (SqlException ex) when (ex.Number == 2627)
{
    // 处理唯一键冲突
}
catch (SqlException ex)
{
    // 通用SQL错误处理
}
finally
{
    // 资源释放
}

8. 关联技术扩展

8.1 Dapper微ORM整合

public IEnumerable<Product> QueryWithDapper()
{
    using (var conn = new SqlConnection(connectionString))
    {
        return conn.Query<Product>(
            "SELECT TOP 10 * FROM Products WHERE Price > @price",
            new { price = 100m });
    }
}

8.2 事务处理示例

using (var transaction = conn.BeginTransaction())
{
    try
    {
        var cmd1 = new SqlCommand("UPDATE ...", conn, transaction);
        cmd1.ExecuteNonQuery();
        
        var cmd2 = new SqlCommand("INSERT ...", conn, transaction);
        cmd2.ExecuteNonQuery();
        
        transaction.Commit();
    }
    catch
    {
        transaction.Rollback();
        throw;
    }
}

9. 总结与建议

通过本文的实践示例,我们可以掌握使用System.Data.SqlClient进行数据排序筛选的核心方法。建议在以下情况选择该方案:

  1. 需要精确控制SQL执行计划
  2. 处理复杂的多表关联查询
  3. 执行存储过程和高级T-SQL特性
  4. 对性能有极致要求的场景

对于常规业务系统,建议结合Dapper等轻量级ORM使用,在保持灵活性的同时提升开发效率。始终牢记安全编码原则,特别是在处理动态查询条件时,必须做好输入验证和参数化处理。