VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 编程开发 > c#编程 >
  • 操作MySQL数据库——跨数据库适配

第一部分:C#基础入门
MySQL数据库操作——跨数据库适配
实例介绍
跨数据库适配是企业级应用的核心能力之一:比如从SQL Server迁移到MySQL降低成本,或者同时支持多个数据库满足客户需求。EF Core的抽象数据库提供者模型让这一切变得简单——实体模型不变,仅通过配置切换数据库。本节通过电商系统从SQL Server到MySQL的迁移场景,带你掌握跨数据库适配的全流程:多数据库提供者配置、MySQL特有优化、差异处理、配置驱动切换,让你的应用轻vb.net教程C#教程python教程SQL教程access 2010教程松兼容不同数据库。
需求分析
设计一个支持跨数据库的电商商品系统,核心需求:
1.实体模型复用:Product实体不变,同时支持SQL Server和MySQL;
2.MySQL特有配置:字符集(utf8mb4支持emoji)、存储引擎(InnoDB支持事务);
3.差异自动处理:EF Core自动转换分页、函数等数据库特有语法;
4.配置驱动切换:通过appsettings.json选择数据库,无需修改代码;
5.兼容性验证:确保查询、写入在两个数据库上都能正常工作。
代码实现
前置条件:
安装包:Pomelo.EntityFrameworkCore.MySql(MySQL提供者)、Microsoft.EntityFrameworkCore.SqlServer(SQL Server提供者)、Microsoft.Extensions.Configuration.Json;
创建MySQL数据库ECommerceDB_MySQL和SQL Server数据库ECommerceDB_SQLServer。

  1. 实体类(复用不变)
    csharp
	using System;
	using System.ComponentModel.DataAnnotations;
	
	public class Product {
	public int Id { get; set; }
	
	[Required]
	[MaxLength(100)] // 跨数据库兼容:MySQL映射为varchar(100),SQL Server为nvarchar(100)
	public string Name { get; set; } = string.Empty;
	
	[Required]
	[MaxLength(50)]
	public string Category { get; set; } = string.Empty;
	
	public decimal Price { get; set; }
	public int Stock { get; set; }
	public DateTime UpdateTime { get; set; } = DateTime.Now;
	}
  1. 跨数据库DbContext配置
    csharp
	using Microsoft.EntityFrameworkCore;
	using Microsoft.Extensions.Configuration;
	using Pomelo.EntityFrameworkCore.MySql.Infrastructure;
	
	public class ECommerceDbContext : DbContext {
	private readonly IConfiguration _config;
	public DbSet<Product> Products { get; set; }
	
	public ECommerceDbContext(IConfiguration config) => _config = config;
	
	protected override void OnConfiguring(DbContextOptionsBuilder options) {
	// 从配置文件读取数据库类型和连接字符串
	var dbProvider = _config["DatabaseProvider"];
	var connStr = _config.GetConnectionString(dbProvider);
	
	switch (dbProvider) {
	case "MySQL":
	// MySQL配置:指定服务器版本、字符集、存储引擎
	options.UseMySql(
	connStr,
	ServerVersion.AutoDetect(connStr), // 自动检测MySQL版本
	mysqlOptions => mysqlOptions
	.CharSet(CharSet.Utf8mb4) // 支持emoji的字符集
	.UseInnoDB() // 启用InnoDB存储引擎(事务+外键)
	.MigrationsHistoryTable("__EFMigrationsHistory", "ecommerce") // 指定迁移表位置
	);
	break;
	case "SQLServer":
	// SQL Server配置
	options.UseSqlServer(connStr);
	break;
	default:
	throw new ArgumentException("不支持的数据库类型");
	}
	
	// 启用日志(调试用)
	options.LogTo(Console.WriteLine);
	}
	
	protected override void OnModelCreating(ModelBuilder model) {
	// 跨数据库通用配置:Product表名、索引
	model.Entity<Product>()
	.ToTable("Products")
	.HasIndex(p => p.Category); // 通用索引配置
	
	// MySQL特有配置:针对MySQL单独优化(条件编译可选,但配置驱动更灵活)
	if (_config["DatabaseProvider"] == "MySQL") {
	model.Entity<Product>()
	.Property(p => p.Name)
	.HasColumnType("varchar(100)"); // 明确指定MySQL类型(可选,EF Core自动映射)
	}
	}
	}
  1. 配置文件(appsettings.json)
    json
	{
	"DatabaseProvider": "MySQL", // 切换为"SQLServer"即可切换数据库
	"ConnectionStrings": {
	"MySQL": "server=localhost;port=3306;database=ECommerceDB_MySQL;user=root;password=your_password;CharSet=utf8mb4;",
	"SQLServer": "Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=ECommerceDB_SQLServer;Integrated Security=True;"
	}
	}
  1. 跨数据库操作示例
    csharp
	using System;
	using System.Linq;
	using System.Threading.Tasks;
	using Microsoft.Extensions.DependencyInjection;
	using Microsoft.Extensions.Configuration;
	
	class Program {
	static async Task Main() {
	// 加载配置文件
	var config = new ConfigurationBuilder()
	.AddJsonFile("appsettings.json")
	.Build();
	
	// 依赖注入配置
	var services = new ServiceCollection()
	.AddSingleton<IConfiguration>(config)
	.AddDbContext<ECommerceDbContext>()
	.BuildServiceProvider();
	
	var dbContext = services.GetRequiredService<ECommerceDbContext>();
	
	// 1. 写入数据(跨数据库兼容)
	var newProduct = new Product {
	Name = "无线耳机",
	Category = "Electronics",
	Price = 199.99m,
	Stock = 100
	};
	dbContext.Products.Add(newProduct);
	await dbContext.SaveChangesAsync();
	Console.WriteLine($"写入商品:ID={newProduct.Id}");
	
	// 2. 查询数据(跨数据库兼容:EF Core自动转换分页语法)
	var products = await dbContext.Products
	.Where(p => p.Category == "Electronics")
	.OrderBy(p => p.Price)
	.Skip(0) // MySQL→LIMIT 0,5;SQL Server→OFFSET 0 FETCH NEXT5 ROWS ONLY
	.Take(5)
	.ToListAsync();
	Console.WriteLine($"查询到{products.Count}个商品");
	}
	}

逐行讲解

  1. DbContext配置关键代码
    OnConfiguring:根据DatabaseProvider配置选择数据库提供者。MySQL用UseMySql(Pomelo包),SQL Server用UseSqlServer。
    MySQL特有配置:
    oCharSet.Utf8mb4:解决MySQL默认utf8不支持emoji的问题;
    oUseInnoDB:启用事务和外键约束(MyISAM不支持);
    oMigrationsHistoryTable:指定迁移表的位置(避免与其他应用冲突)。
    OnModelCreating:通用配置(表名、索引)+ MySQL特有优化(如明确列类型)。
  2. 跨数据库差异处理
    分页语法:Skip(0).Take(5)在MySQL中转换为LIMIT 0,5,SQL Server转换为OFFSET 0 FETCH NEXT5 ROWS ONLY——EF Core自动处理,无需手动修改。
    日期函数:DateTime.Now在MySQL中转换为NOW(),SQL Server转换为GETDATE()——EF Core的DateTime类型自动映射。
    字符串类型:MaxLength(100)在MySQL中映射为varchar(100),SQL Server映射为nvarchar(100)——EF Core根据提供者自动适配。
  3. 配置驱动切换
    appsettings.json:修改DatabaseProvider为"SQLServer"即可切换到SQL Server,无需修改代码。
    连接字符串:不同数据库的连接字符串通过ConnectionStrings节点区分,确保安全隔离。
    基础知识拓展
  4. EF Core跨数据库适配原理
    EF Core采用抽象数据库提供者模型:
    核心层:定义通用接口(如IDbContextOptionsBuilder);
    提供者层:每个数据库实现自己的提供者(如Pomelo.MySql、SQL Server);
    应用层:通过配置选择提供者,实体模型和业务逻辑不变。
    这种模型让跨数据库适配变得简单——开发者只需关注通用LINQ查询,无需关心数据库特有语法。
  5. MySQL与SQL Server关键差异对比
特性 MySQL SQL Server EF Core适配方式
字符集 utf8mb4(支持emoji) nvarchar(原生支持Unicode) 配置CharSet.Utf8mb4(MySQL)
存储引擎 InnoDB(事务)/MyISAM(性能) 单一存储引擎(支持事务) 配置UseInnoDB(MySQL)
分页语法 LIMIT offset, count OFFSET ... FETCH NEXT ... 用Skip()+Take(),EF Core自动转换
日期函数 NOW() GETDATE() 用DateTime.Now,EF Core自动映射
自增主键 AUTO_INCREMENT IDENTITY(1,1) 用[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
  1. 跨数据库适配最佳实践
    1.避免数据库特有函数:不要用DbFunctions的数据库特有方法(如DbFunctions.Like),优先用LINQ的Contains();
    2.用配置驱动切换:通过配置文件而非条件编译切换数据库,提高灵活性;
    3.测试兼容性:对每个数据库进行单元测试,确保查询和写入正常;
    4.优化数据库特有部分:针对MySQL的索引、字符集,SQL Server的分区表等进行单独优化;
    5.使用通用数据类型:优先用EF Core的通用类型(如string、decimal),避免数据库特有类型(如MySQL的TEXT)。
    总结
    跨数据库适配的核心是抽象与复用:EF Core的提供者模型抽象了数据库差异,让实体模型和业务逻辑保持不变;配置驱动切换让系统灵活兼容不同数据库。通过本节的学习,你可以轻松实现从SQL Server到MySQL的迁移,或者同时支持多个数据库——只需修改配置,无需重构代码。
    关键Takeaway:跨数据库适配不是“一刀切”,而是“通用部分复用+特有部分优化”。EF Core帮你处理大部分差异,你只需关注数据库特有的优化(如MySQL的字符集、存储引擎),就能打造出灵活、兼容的企业级应用。

本站原创,转载请注明出处:


相关教程