☰
.NET连接MySQL的三种主流方案与优化实践
2026/11/5 2:25:18 网站建设 项目流程

1. 项目概述

在.NET生态中与MySQL数据库建立连接是许多开发者日常工作中不可或缺的基础技能。不同于SQL Server与.NET平台的原生兼容性,MySQL作为开源数据库的代表,在C#项目中的集成需要更多技术细节的考量。本文将深入剖析ADO.NET、Entity Framework Core以及Dapper三种主流方案,从基础连接字符串配置到高级ORM映射,全面覆盖实际开发中的各类场景。

2. 环境准备与基础配置

2.1 必要组件安装

首先需要通过NuGet获取MySQL官方提供的连接驱动:

Install-Package MySql.Data Install-Package MySql.Data.EntityFramework

对于Entity Framework Core方案需额外安装:

Install-Package Pomelo.EntityFrameworkCore.MySql

注意:Oracle官方提供的MySQL Connector/NET与社区驱动的Pomelo.EntityFrameworkCore.MySql在功能支持上存在差异,生产环境建议进行性能测试后再做选择。

2.2 连接字符串详解

基础连接字符串包含以下关键参数:

"Server=127.0.0.1;Port=3306;Database=mydb;Uid=root;Pwd=123456;"

高级配置项示例:

"Server=localhost;Database=test;Uid=appuser;Pwd=securePwd123; ConnectionTimeout=30;Pooling=true;MinPoolSize=5;MaxPoolSize=100; CharSet=utf8mb4;AllowPublicKeyRetrieval=true;"
  • Pooling:连接池默认开启,建议根据并发量调整池大小
  • CharSet:必须明确指定为utf8mb4以支持完整Unicode字符集
  • AllowPublicKeyRetrieval:SSL连接时的特殊配置项

3. 核心连接方案实现

3.1 ADO.NET原生方式

基础连接示例:

using MySql.Data.MySqlClient; string connStr = "server=localhost;user=root;database=test;port=3306;password=123456"; using (MySqlConnection conn = new MySqlConnection(connStr)) { try { conn.Open(); string sql = "SELECT * FROM users WHERE id=@id"; MySqlCommand cmd = new MySqlCommand(sql, conn); cmd.Parameters.AddWithValue("@id", 1); using (MySqlDataReader rdr = cmd.ExecuteReader()) { while (rdr.Read()) { Console.WriteLine(rdr["username"]); } } } catch (Exception ex) { Console.WriteLine(ex.ToString()); } }

事务处理模板:

using (MySqlTransaction trans = conn.BeginTransaction()) { try { // 执行多个命令 trans.Commit(); } catch { trans.Rollback(); throw; } }

3.2 Entity Framework Core集成

DbContext配置示例:

services.AddDbContext<AppDbContext>(options => options.UseMySql( Configuration.GetConnectionString("Default"), new MySqlServerVersion(new Version(8, 0, 26)) ));

实体类映射示例:

[Table("products")] public class Product { [Key] [Column("product_id")] public int Id { get; set; } [Required] [MaxLength(100)] [Column("product_name")] public string Name { get; set; } [Column(TypeName = "DECIMAL(10,2)")] public decimal Price { get; set; } }

3.3 Dapper轻量级方案

基础查询示例:

using Dapper; var users = conn.Query<User>("SELECT * FROM users WHERE status = @status", new { status = 1 });

多表查询处理:

var sql = @"SELECT p.*, c.Name as CategoryName FROM products p JOIN categories c ON p.CategoryId = c.Id"; var products = conn.Query<Product, Category, Product>(sql, (product, category) => { product.Category = category; return product; }, splitOn: "CategoryName");

4. 性能优化策略

4.1 连接池配置建议

参数默认值生产建议说明
Poolingtruetrue必须开启
MinPoolSize05-10预热连接数
MaxPoolSize100100-200根据服务器配置调整
ConnectionTimeout1530超时秒数
ConnectionLifeTime0300连接回收时间(秒)

4.2 批量操作优化

使用MySqlBulkLoader实现高效导入:

var bulk = new MySqlBulkLoader(conn) { TableName = "large_data", FieldTerminator = ",", LineTerminator = "\n", FileName = "data.csv" }; bulk.Load();

EF Core批量插入扩展:

context.BulkInsert(entities, options => { options.BatchSize = 1000; options.InsertIfNotExists = true; });

5. 安全防护措施

5.1 凭证管理方案

推荐采用Azure Key Vault或AWS Secrets Manager动态获取凭据:

var secretClient = new SecretClient( new Uri(keyVaultUrl), new DefaultAzureCredential()); string connStr = await secretClient .GetSecretAsync("mysql-conn-str");

5.2 SQL注入防护

参数化查询的三种正确姿势:

// ADO.NET方式 cmd.Parameters.AddWithValue("@param", value); // Dapper方式 conn.Query("SELECT * FROM table WHERE id=@id", new { id }); // EF Core方式 context.Users.FromSqlInterpolated($"SELECT * FROM users WHERE id={id}");

6. 异常处理与调试

6.1 常见错误代码处理

错误代码含义处理方案
1045访问拒绝检查凭据和主机权限
2002连接超时验证网络和防火墙设置
1213死锁重试事务或优化查询
1062键重复实现upsert逻辑

6.2 诊断日志配置

在appsettings.json中配置详细日志:

{ "Logging": { "MySql": { "LogLevel": { "MySql.Data": "Debug", "Microsoft.EntityFrameworkCore.Database.Command": "Information" } } } }

7. 高级应用场景

7.1 JSON类型支持

MySQL 8.0+的JSON操作示例:

// 查询JSON字段 var result = conn.QuerySingle<string>( "SELECT JSON_EXTRACT(profile, '$.address') FROM users WHERE id=1"); // EF Core更新JSON字段 context.Users .Where(u => u.Id == 1) .ExecuteUpdate(u => u .SetProperty(p => p.ProfileJson, p => "JSON_SET(p.ProfileJson, '$.phone', '123456')"));

7.2 分布式事务处理

使用TransactionScope实现跨库事务:

using (var scope = new TransactionScope( TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted })) { // 操作多个数据库 scope.Complete(); }

8. 架构设计建议

8.1 分层设计示例

推荐的项目结构:

- MyProject.Data ├── Repositories (具体数据操作) ├── Entities (领域模型) └── DbContexts (数据库上下文) - MyProject.Services (业务逻辑层) - MyProject.Api (表现层)

8.2 读写分离实现

基于代理模式的实现方案:

public class DbConnectionFactory { private readonly string _writeConnStr; private readonly string _readConnStr; public IDbConnection CreateWriteConnection() => new MySqlConnection(_writeConnStr); public IDbConnection CreateReadConnection() => new MySqlConnection(_readConnStr); }

9. 迁移与部署

9.1 数据库变更管理

EF Core迁移命令示例:

# 创建迁移 dotnet ef migrations add InitialCreate # 应用迁移 dotnet ef database update # 生成SQL脚本 dotnet ef migrations script --output migrations.sql

9.2 Docker部署配置

docker-compose.yml示例:

version: '3' services: mysql: image: mysql:8.0 environment: MYSQL_ROOT_PASSWORD: securepassword MYSQL_DATABASE: appdb ports: - "3306:3306" volumes: - mysql_data:/var/lib/mysql volumes: mysql_data:

10. 实际案例解析

电商项目中的典型数据访问模式:

// 商品分页查询 public async Task<PageResult<Product>> SearchProducts(ProductQuery query) { var baseQuery = context.Products .Where(p => p.CategoryId == query.CategoryId); if (!string.IsNullOrEmpty(query.Keyword)) { baseQuery = baseQuery.Where(p => EF.Functions.Like(p.Name, $"%{query.Keyword}%")); } var total = await baseQuery.CountAsync(); var items = await baseQuery .OrderBy(p => p.Price) .Skip((query.Page - 1) * query.PageSize) .Take(query.PageSize) .ToListAsync(); return new PageResult<Product>(items, total); }

在长期维护企业级.NET应用的过程中,我发现MySQL连接稳定性很大程度上取决于连接池参数的合理配置。特别是在微服务架构下,建议为每个服务实例设置独立的连接池前缀(通过在连接字符串中添加ApplicationName参数),这样可以更精确地监控和管理各个服务的数据库连接状态。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询