《.Net中操作MySql数据库》
在.NET开发中,MySQL作为一款开源的关系型数据库,因其高性能、易用性和跨平台特性,被广泛应用于各类Web和桌面应用程序。本文将详细介绍如何在.NET环境中通过C#语言操作MySQL数据库,涵盖从环境配置、基础CRUD操作到高级特性(如事务处理、存储过程调用)的完整流程,帮助开发者快速掌握MySQL与.NET的集成开发。
一、环境准备与依赖安装
在.NET项目中操作MySQL,首先需要安装MySQL官方提供的.NET连接器(Connector/NET),或通过NuGet包管理器安装更轻量级的依赖库。
1.1 安装MySQL Connector/NET
MySQL Connector/NET是官方提供的ADO.NET数据提供程序,支持与MySQL的完整交互。安装步骤如下:
- 通过Visual Studio的NuGet包管理器控制台执行:
Install-Package MySql.Data
或通过.NET CLI:
dotnet add package MySql.Data
1.2 替代方案:MySqlConnector
MySqlConnector是一个开源的异步MySQL客户端,性能优于官方驱动,尤其适合高并发场景。安装命令:
Install-Package MySqlConnector
本文后续示例将基于MySqlConnector进行演示。
二、建立数据库连接
连接MySQL数据库需要配置连接字符串,包含服务器地址、端口、数据库名、用户名和密码等信息。
2.1 连接字符串格式
标准连接字符串示例:
string connectionString = "Server=localhost;Port=3306;Database=testdb;Uid=root;Pwd=password;";
参数说明:
-
Server
:MySQL服务器地址(本地为localhost) -
Port
:默认3306,若修改需指定 -
Database
:目标数据库名 -
Uid
/Pwd
:用户名和密码 -
SslMode
:可选,指定SSL模式(如None、Preferred)
2.2 使用连接池优化性能
为避免频繁创建和销毁连接,建议启用连接池:
string connectionString = "Server=localhost;Database=testdb;Uid=root;Pwd=password;Pooling=true;MinimumPoolSize=5;MaximumPoolSize=100;";
参数说明:
-
Pooling
:true表示启用连接池 -
MinimumPoolSize
:连接池最小连接数 -
MaximumPoolSize
:连接池最大连接数
三、基础CRUD操作
CRUD(创建、读取、更新、删除)是数据库操作的核心,下面通过完整示例演示。
3.1 创建表结构
假设需创建用户表(users),包含ID、用户名、邮箱和创建时间字段:
using MySqlConnector;
using System;
class Program
{
static void Main()
{
string connectionString = "Server=localhost;Database=testdb;Uid=root;Pwd=password;";
using (var connection = new MySqlConnection(connectionString))
{
connection.Open();
string sql = @"CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL,
email VARCHAR(100) NOT NULL UNIQUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)";
using (var command = new MySqlCommand(sql, connection))
{
command.ExecuteNonQuery();
Console.WriteLine("表创建成功!");
}
}
}
}
3.2 插入数据(Create)
向users表插入一条记录:
using (var connection = new MySqlConnection(connectionString))
{
connection.Open();
string sql = "INSERT INTO users (username, email) VALUES (@username, @email)";
using (var command = new MySqlCommand(sql, connection))
{
command.Parameters.AddWithValue("@username", "john_doe");
command.Parameters.AddWithValue("@email", "john@example.com");
int rowsAffected = command.ExecuteNonQuery();
Console.WriteLine($"插入成功,影响行数:{rowsAffected}");
}
}
关键点:
- 使用参数化查询(
@username
)防止SQL注入 -
ExecuteNonQuery()
返回受影响的行数
3.3 查询数据(Read)
查询所有用户信息:
using (var connection = new MySqlConnection(connectionString))
{
connection.Open();
string sql = "SELECT id, username, email, created_at FROM users";
using (var command = new MySqlCommand(sql, connection))
{
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
Console.WriteLine($"ID: {reader["id"]}, 用户名: {reader["username"]}, 邮箱: {reader["email"]}, 创建时间: {reader["created_at"]}");
}
}
}
}
进阶查询:带条件的分页查询
string sql = "SELECT * FROM users WHERE username LIKE @searchTerm ORDER BY id LIMIT @offset, @pageSize";
command.Parameters.AddWithValue("@searchTerm", "%john%");
command.Parameters.AddWithValue("@offset", 0);
command.Parameters.AddWithValue("@pageSize", 10);
3.4 更新数据(Update)
更新用户邮箱:
using (var connection = new MySqlConnection(connectionString))
{
connection.Open();
string sql = "UPDATE users SET email = @newEmail WHERE id = @userId";
using (var command = new MySqlCommand(sql, connection))
{
command.Parameters.AddWithValue("@newEmail", "john.doe@example.com");
command.Parameters.AddWithValue("@userId", 1);
int rowsAffected = command.ExecuteNonQuery();
Console.WriteLine($"更新成功,影响行数:{rowsAffected}");
}
}
3.5 删除数据(Delete)
删除ID为1的用户:
using (var connection = new MySqlConnection(connectionString))
{
connection.Open();
string sql = "DELETE FROM users WHERE id = @userId";
using (var command = new MySqlCommand(sql, connection))
{
command.Parameters.AddWithValue("@userId", 1);
int rowsAffected = command.ExecuteNonQuery();
Console.WriteLine($"删除成功,影响行数:{rowsAffected}");
}
}
四、高级特性
4.1 事务处理
事务确保一组操作要么全部成功,要么全部回滚。示例:转账场景
using (var connection = new MySqlConnection(connectionString))
{
connection.Open();
using (var transaction = connection.BeginTransaction())
{
try
{
// 从账户A扣款
string debitSql = "UPDATE accounts SET balance = balance - @amount WHERE id = @fromId";
using (var command = new MySqlCommand(debitSql, connection, transaction))
{
command.Parameters.AddWithValue("@amount", 100);
command.Parameters.AddWithValue("@fromId", 1);
command.ExecuteNonQuery();
}
// 向账户B存款
string creditSql = "UPDATE accounts SET balance = balance + @amount WHERE id = @toId";
using (var command = new MySqlCommand(creditSql, connection, transaction))
{
command.Parameters.AddWithValue("@amount", 100);
command.Parameters.AddWithValue("@toId", 2);
command.ExecuteNonQuery();
}
transaction.Commit();
Console.WriteLine("转账成功!");
}
catch (Exception ex)
{
transaction.Rollback();
Console.WriteLine($"转账失败:{ex.Message}");
}
}
}
4.2 调用存储过程
假设已创建存储过程GetUserByEmail
:
DELIMITER //
CREATE PROCEDURE GetUserByEmail(IN emailParam VARCHAR(100))
BEGIN
SELECT * FROM users WHERE email = emailParam;
END //
DELIMITER ;
C#调用代码:
using (var connection = new MySqlConnection(connectionString))
{
connection.Open();
using (var command = new MySqlCommand("GetUserByEmail", connection))
{
command.CommandType = System.Data.CommandType.StoredProcedure;
command.Parameters.AddWithValue("emailParam", "john@example.com");
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
Console.WriteLine($"ID: {reader["id"]}, 用户名: {reader["username"]}");
}
}
}
}
4.3 异步操作
MySqlConnector支持异步方法,避免阻塞主线程。示例:异步查询
using System.Threading.Tasks;
async Task QueryUsersAsync()
{
using (var connection = new MySqlConnection(connectionString))
{
await connection.OpenAsync();
string sql = "SELECT * FROM users";
using (var command = new MySqlCommand(sql, connection))
{
using (var reader = await command.ExecuteReaderAsync())
{
while (await reader.ReadAsync())
{
Console.WriteLine(reader["username"]);
}
}
}
}
}
五、性能优化与最佳实践
5.1 使用using语句管理资源
所有IDbConnection、IDbCommand和IDataReader对象应放在using块中,确保及时释放资源。
5.2 参数化查询防注入
永远不要拼接SQL字符串,始终使用参数化查询:
// 错误示例(易受SQL注入攻击)
string sql = $"SELECT * FROM users WHERE username = '{username}'";
// 正确示例
string sql = "SELECT * FROM users WHERE username = @username";
command.Parameters.AddWithValue("@username", username);
5.3 批量操作优化
批量插入数据时,使用MySqlBulkCopy(需MySQL 8.0+)或事务+批量命令:
// 示例:事务内批量插入
using (var transaction = connection.BeginTransaction())
{
for (int i = 0; i
5.4 连接复用
在Web应用中,可通过依赖注入复用DbConnection实例(需注意线程安全)。
六、常见问题与解决方案
6.1 连接失败排查
- 检查MySQL服务是否运行:
sudo service mysql status
- 验证用户名/密码是否正确
- 确认防火墙是否放行3306端口
- 检查用户是否有远程访问权限(若从非本地连接)
6.2 时区问题
MySQL默认使用服务器时区,可能导致时间字段存储异常。解决方案:
- 连接字符串中指定时区:
Charset=utf8mb4;TimeZone=+08:00;
- 或在查询时转换:
CONVERT_TZ(created_at, '+00:00', '+08:00')
6.3 字符集配置
为避免中文乱码,建议连接字符串中明确指定字符集:
string connectionString = "Server=localhost;Database=testdb;Uid=root;Pwd=password;Charset=utf8mb4;";
七、总结与扩展
本文详细介绍了.NET中操作MySQL数据库的全流程,从环境配置到高级特性,覆盖了实际开发中的核心场景。开发者可根据项目需求选择合适的驱动(官方Connector或MySqlConnector),并遵循最佳实践确保代码安全性和性能。
扩展方向:
- 使用Entity Framework Core进行ORM映射
- 集成Dapper轻量级ORM简化CRUD
- 实现读写分离架构
- 结合Redis缓存热点数据
关键词:.NET、C#、MySQL、数据库操作、CRUD、事务处理、存储过程、异步编程、连接池、参数化查询
简介:本文系统讲解了在.NET环境中通过C#操作MySQL数据库的方法,涵盖连接配置、基础CRUD操作、事务管理、存储过程调用等核心功能,并提供性能优化建议和常见问题解决方案,适合.NET开发者快速掌握MySQL集成开发。