四.Ado.Net

2026-05-12 08:02 153 阅读

Ado.Net 笔记整理

Ado(ActiveX Data Objects) 一个用于c# 操作数据库的框架,是一个com组件库。

优点:执行效率高

缺点:开发效率慢



当前笔记开发环境为:vs2022、mysql8、.net 8

1.Connection连接对象

Connection是数据库连接对象,用于于数据库建立连接。sqlServer是SqlConnection,MySql是MySqlConnection,这些类都实现IDbConnection接口。

/**
 * 1.nuget安装Mysql.Data
 */

/**
 * 2.准备mysql连接字符串
 */
string server = "www.diandiandidi.club"; // 服务器地址
string port = "3306"; // 端口号
string database = "test"; // 数据库名称
string uid = "dddd"; // 用户名
string pwd = "@DianDianDiDi7933"; // 密码
string connStr = $"Server={server};Port={port};Database={database};Uid={uid};Pwd={pwd};";

/**
 * 3.创建mysql连接对象
 * MySqlConnection在MySql.Data.MySqlClient下
 */
var mySqlConnection = new MySqlConnection(connStr);

Console.WriteLine($"连接状态:{mySqlConnection.State}");
Console.WriteLine($"数据库:{mySqlConnection.Database}");
Console.WriteLine($"超时时间:{mySqlConnection.ConnectionTimeout}秒");

/**
 * 4.打开连接
 */
mySqlConnection.Open();
Console.WriteLine($"mysql服务器版本:{mySqlConnection.ServerVersion}");

/**
 * 5.最后一定要关闭连接
 */
mySqlConnection.Close();

/**
 * 5.1 或者使用using语句自动关闭连接
 */
//using (var connection = new MySqlConnection(connStr))
//{
//    connection.Open();
//}

2.SqlCommand命令对象

MySqlCommand和MySqlConnection同样属于非托管资源,需要手动释放

private static void TestInsertReturnId(MySqlConnection mySqlConnection)
{
    string sql = "INSERT INTO roles (role_name, description) VALUES (@role_name, @description);SELECT LAST_INSERT_ID();";
    using var mySqlCommand = new MySqlCommand(sql, mySqlConnection);
    mySqlCommand.Parameters.AddWithValue("@role_name", "Tourist2");
    mySqlCommand.Parameters.AddWithValue("@description", "游客2,无权限");
    var result = mySqlCommand.ExecuteScalar();
    Console.WriteLine($"自增id:{result}");
}

/// <summary>
/// 测试获取首行首列
/// </summary>
/// <param name="mySqlConnection"></param>
/// <returns></returns>
private static void TestScalar(MySqlConnection mySqlConnection)
{
    string sql = "SELECT COUNT(1) FROM users";
    using var mySqlCommand = new MySqlCommand(sql, mySqlConnection);
    var result = mySqlCommand.ExecuteScalar();
    Console.WriteLine($"返回值:{result}");
}

/// <summary>
/// 测试插入(删除、更新和插入的方法一致)
/// </summary>
/// <param name="mySqlConnection"></param>
private static void TestInsert(MySqlConnection mySqlConnection)
{
    string sql = "INSERT INTO roles (role_name, description) VALUES (@role_name, @description)";
    using var mySqlCommand = new MySqlCommand(sql, mySqlConnection);
    mySqlCommand.Parameters.AddWithValue("@role_name", "Tourist");
    mySqlCommand.Parameters.AddWithValue("@description", "游客,无权限");
    int rowsAffected = mySqlCommand.ExecuteNonQuery();
    Console.WriteLine($"插入成功 {rowsAffected} 条数据。");
}

3.SqlDataReader 数据读取

从数据库中只进的行流读取数据,整个过程需要一直保持与数据库连接。

/// <summary>
/// 测试查询
/// </summary>
private static void TestSelect(MySqlConnection mySqlConnection)
{
    string sql = "SELECT * FROM users";
    using var mySqlCommand = new MySqlCommand(sql, mySqlConnection);
    using var mySqlDataReader = mySqlCommand.ExecuteReader();
    while (mySqlDataReader.Read())
    {
        Console.WriteLine(mySqlDataReader["user_id"] + "--" + mySqlDataReader["username"]);
    }
}

判断读取的某个数据是否为空

if(mySqlDataReader["user_id"] is not DBNull)
{
}

4.连接模式和断开模式

连接模式:需要一直保持与数据库连接,适用于大量数据,例如SqlDataReader

断开模式:可以一次性读取数据,之后断开连接,适用于小量数据,例如SqlDataAdapter

5.SqlDataAdapter 适配器

private static void TestSelect(MySqlConnection mySqlConnection)
{
    using var adapter = new MySqlDataAdapter();
    using var cmd = new MySqlCommand("SELECT * FROM users", mySqlConnection);
    adapter.SelectCommand = cmd;

    /**
     * DataSet:小型数据集。
     * DataSet类实现了IDisposable接口,主要管理的是内存中的数据,
     * 不直接持有非托管资源,大多数情况下不需要​​为 DataSet 使用 using 语句
     */
    using var ds = new DataSet();
    // 适配器填充数据集
    adapter.Fill(ds);
    // 获取第一个表
    DataTable table = ds.Tables[0];

    // 获取第一行第一列的值
    object value = table.Rows[0][0];

    // 获取第一行"Name"列的值
    string name = table.Rows[0]["username"].ToString();

    // 遍历所有行
    foreach (DataRow row in table.Rows)
    {
        Console.WriteLine($"ID: {row["user_id"]}, Name: {row["username"]}");
    }
}

6.数据连接池

通过复用数据库连接来减少创建和销毁连接的开销

工作原理:

1.当应用程序请求连接时,连接池首先检查是否有可用的空闲连接 2.如果有则直接返回,没有则创建新连接 3.使用完毕后连接返回连接池而非真正关闭 4.连接池维护一定数量的活跃连接 

SqlClient(SQL Server)、OracleClient、MySqlClient、Npgsql(PostgreSQL)均默认开启连接池,默认最大连接数为100。

Pooling=true; // 是否启用连接池(默认true) Min Pool Size=5; // 最小连接数(默认0) Max Pool Size=100; // 最大连接数(默认100)



7.事务操作

基本事务模式

var myTransaction = mySqlConnection.BeginTransaction();
try
{
    myTransaction.Commit();
}
catch (Exception e)
{
    Debug.WriteLine(e);
    myTransaction.Rollback();
}
finally
{
    mySqlConnection.Close();
}

事务隔离级别

var isoLevel = System.Data.IsolationLevel.ReadCommitted;
var myTransaction = mySqlConnection.BeginTransaction(isoLevel);
隔离级别	脏读	不可重复读	幻读	描述
ReadUncommitted	✓	✓	✓	最低隔离级别
ReadCommitted	×	✓	✓	默认级别,防止脏读
RepeatableRead	×	×	✓	防止不可重复读
Serializable	×	×	×	最高隔离级别
Snapshot	×	×	×	使用行版本控制

保存点

var myTransaction = mySqlConnection.BeginTransaction();
try
{
    // ······

    //创建保存点
    myTransaction.Save("AfterOrderCreated");

    // ······

    myTransaction.Commit();
}
catch (Exception e)
{
    // 只回滚到保存点
    myTransaction.Rollback("AfterOrderCreated");
}
finally
{
    myTransaction.Rollback();
}



8.DbHelper



public class DbHelper
{
    private readonly string _connectionString;

    public DbHelper(string connectionString)
    {
        _connectionString = connectionString;
    }

    // 打开数据库连接
    private MySqlConnection GetConnection()
    {
        var connection = new MySqlConnection(_connectionString);
        connection.Open();
        return connection;
    }

    /// <summary>
    /// 执行查询并返回 MySqlDataReader
    /// </summary>
    public MySqlDataReader ExecuteReader(string query, params MySqlParameter[] parameters)
    {
        var connection = GetConnection();
        var command = new MySqlCommand(query, connection);
        if (parameters != null)
        {
            command.Parameters.AddRange(parameters);
        }
        return command.ExecuteReader(CommandBehavior.CloseConnection);
    }

    /// <summary>
    /// 执行查询并返回 DataTable
    /// </summary>
    public DataTable ExecuteQuery(string query, params MySqlParameter[] parameters)
    {
        using (var connection = GetConnection())
        using (var command = new MySqlCommand(query, connection))
        {
            if (parameters != null)
            {
                command.Parameters.AddRange(parameters);
            }

            using (var adapter = new MySqlDataAdapter(command))
            {
                var dataTable = new DataTable();
                adapter.Fill(dataTable);
                return dataTable;
            }
        }
    }

    /// <summary>
    /// 执行非查询命令(如 INSERT、UPDATE、DELETE),返回受影响的行数
    /// </summary>
    /// <returns></returns>
    public int ExecuteNonQuery(string query, params MySqlParameter[] parameters)
    {
        using (var connection = GetConnection())
        using (var command = new MySqlCommand(query, connection))
        {
            if (parameters != null)
            {
                command.Parameters.AddRange(parameters);
            }

            return command.ExecuteNonQuery();
        }
    }

    /// <summary>
    /// 执行单一结果查询(如 COUNT、SUM),返回结果
    /// </summary>
    public object ExecuteScalar(string query, params MySqlParameter[] parameters)
    {
        using (var connection = GetConnection())
        using (var command = new MySqlCommand(query, connection))
        {
            if (parameters != null)
            {
                command.Parameters.AddRange(parameters);
            }

            return command.ExecuteScalar();
        }
    }
}