如何从MSSQL导出数据并在C#应用中自动填充EF迁移后的数据库?
解决方案:自动化填充EF重建后的SQL Server数据库
一、快速导出数据库数据(SSMS工具)
- 生成架构+数据脚本:在SSMS中右键目标数据库 → 任务 → 生成脚本。全选需要导出的表,进入「设置脚本编写选项」,将「类型的数据脚本」改为「架构和数据」,可调整「每批语句数」「脚本大小」适配大数据量,避免单脚本过大。
- 导出BACPAC文件:右键数据库 → 任务 → 导出数据层应用程序。BACPAC包含完整架构与数据,体积更小,适合大规模数据导出,后续可通过代码直接还原。
二、C#应用启动自动填充方案
1. EF Core自动生成种子数据(适配复杂关联)
无需手动编写JSON,借助工具自动生成带关联关系的种子数据:
- 用EF Core Power Tools连接目标数据库,选择「生成实体类和种子数据」,工具会自动读取现有数据,生成包含
HasData配置的DbContext代码,关联关系会被自动处理。 - 将生成的
HasData配置加入DbContext的OnModelCreating方法,后续执行Add-Migration时种子数据会被写入迁移脚本,应用启动执行MigrateAsync()后,数据会自动填充。
2. BACPAC自动还原(超大规模数据首选)
数据量极大时,种子数据效率偏低,可直接还原BACPAC:
- 调用SQL Server自带的
SqlPackage.exe(路径通常为C:\Program Files\Microsoft SQL Server\160\DAC\bin,版本号依SQL Server版本调整),通过C#进程执行还原:
using System.Diagnostics; var bacpacPath = Path.Combine(AppContext.BaseDirectory, "YourDB.bacpac"); var connStr = "Data Source=.;Initial Catalog=YourDB;Integrated Security=True"; var processStartInfo = new ProcessStartInfo { FileName = @"C:\Program Files\Microsoft SQL Server\160\DAC\bin\SqlPackage.exe", Arguments = $"/Action:Import /SourceFile:\"{bacpacPath}\" /TargetConnectionString:\"{connStr}\"", WindowStyle = ProcessWindowStyle.Hidden, CreateNoWindow = true }; using var process = Process.Start(processStartInfo); process?.WaitForExit();
- 在应用启动逻辑中,先检查核心表是否为空,为空则执行上述还原操作。
3. CSV批量导入(中等规模数据)
用SSMS导出各表为CSV,结合SqlBulkCopy高效导入:
- SSMS右键表 → 任务 → 导出数据,选择CSV格式导出。
- C#中用
CsvHelper读取CSV,再通过SqlBulkCopy批量写入:
using System.Data.SqlClient; using CsvHelper; var csvPath = Path.Combine(AppContext.BaseDirectory, "Products.csv"); using var reader = new StreamReader(csvPath); using var csv = new CsvReader(reader, System.Globalization.CultureInfo.InvariantCulture); var records = csv.GetRecords<Product>().ToList(); using var connection = new SqlConnection("YourConnectionString"); connection.Open(); using var bulkCopy = new SqlBulkCopy(connection); bulkCopy.DestinationTableName = "Products"; bulkCopy.WriteToServer(ListToDataTable(records)); // 自行实现List转DataTable方法
三、结合EF迁移的自动化流程
在应用启动时串联迁移与数据填充逻辑:
using Microsoft.EntityFrameworkCore; var host = Host.CreateDefaultBuilder(args) .ConfigureServices(services => { services.AddDbContext<YourDbContext>(options => options.UseSqlServer("YourConnectionString")); }) .Build(); using var scope = host.Services.CreateScope(); var dbContext = scope.ServiceProvider.GetRequiredService<YourDbContext>(); // 自动执行EF迁移 await dbContext.Database.MigrateAsync(); // 检查数据是否存在,为空则触发填充 if (!await dbContext.CoreTable.AnyAsync()) { // 执行上述填充逻辑(种子数据/BACPAC还原/批量导入) } await host.RunAsync();
内容的提问来源于stack exchange,提问作者Raso
相关产品推荐
相关产品推荐

