如何使用C#在ASP.NET Core中将Web API返回的JSON数据自动导入Azure SQL数据库
针对你这种从Web API拉取JSON数据导入Azure SQL,还需要每月自动更新的场景,我整理了几个实用的方案,你可以根据自己的技术栈和需求选择:
方案1:在ASP.NET Core应用内实现(适合需要集成到现有应用的场景)
这个方案把数据拉取、解析、导入和定时任务都整合到你的Web应用里,步骤如下:
1. 定义与JSON匹配的实体类
先创建一个对应JSON结构的实体类,方便后续序列化:
public class TankRecord { public string ts_num { get; set; } public DateTime pl_date_first { get; set; } public DateTime pl_date_last { get; set; } public string pl_num { get; set; } public string pl_vod { get; set; } public decimal tank1_dn { get; set; } public decimal tank2_dn { get; set; } public int tank1_dn_count { get; set; } public int tank2_dn_count { get; set; } }
2. 替换WebClient为HttpClient(推荐)
注意:WebClient已被标记为过时,官方推荐使用HttpClient,先在Program.cs里注册HttpClient单例:
builder.Services.AddHttpClient();
然后在服务/控制器里注入并拉取数据:
private readonly HttpClient _httpClient; private readonly IConfiguration _config; public TankDataService(HttpClient httpClient, IConfiguration config) { _httpClient = httpClient; _config = config; } public async Task<List<TankRecord>> FetchTankDataAsync() { // 配置API认证 var apiCreds = _config.GetSection("ApiCredentials").Get<NetworkCredential>(); var authToken = Convert.ToBase64String(Encoding.ASCII.GetBytes($"{apiCreds.UserName}:{apiCreds.Password}")); _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", authToken); // 拉取JSON数据并反序列化 var jsonString = await _httpClient.GetStringAsync(_config["ApiSettings:DataUrl"]); return JsonSerializer.Deserialize<List<TankRecord>>(jsonString); }
3. 用EF Core导入Azure SQL
首先安装EF Core SQL Server包:Microsoft.EntityFrameworkCore.SqlServer,然后定义DbContext:
public class AppDbContext : DbContext { public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { } public DbSet<TankRecord> TankRecords { get; set; } }
在Program.cs配置Azure SQL连接字符串:
builder.Services.AddDbContext<AppDbContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("AzureSqlConnection")));
然后实现导入逻辑,建议做增量更新避免重复数据:
public async Task ImportTankDataAsync() { var records = await FetchTankDataAsync(); using var context = new AppDbContext(_dbContextOptions); foreach (var record in records) { // 用唯一标识判断数据是否已存在 var existing = await context.TankRecords .FirstOrDefaultAsync(r => r.ts_num == record.ts_num && r.pl_date_last == record.pl_date_last); if (existing == null) { context.TankRecords.Add(record); } else { // 若需要更新现有数据,替换对应字段 existing.tank1_dn = record.tank1_dn; existing.tank2_dn = record.tank2_dn; context.TankRecords.Update(existing); } } await context.SaveChangesAsync(); }
4. 配置每月自动执行
用Hangfire实现定时任务,先安装包:Hangfire.AspNetCore和Hangfire.SqlServer,然后在Program.cs配置:
builder.Services.AddHangfire(config => config.UseSqlServerStorage(builder.Configuration.GetConnectionString("AzureSqlConnection"))); builder.Services.AddHangfireServer();
最后注册每月执行的任务:
app.UseHangfireDashboard(); // 每月1号凌晨执行一次 RecurringJob.AddOrUpdate<TankDataService>(s => s.ImportTankDataAsync(), Cron.Monthly(1, 0));
方案2:用Azure Data Factory实现无代码自动同步(适合云原生、不想改动应用的场景)
如果不想在应用里加额外逻辑,可以用Azure的云服务完成全流程:
- 步骤1:创建Azure Data Factory资源,进入Data Factory Studio
- 步骤2:新建管道,添加
HTTP活动:配置API地址、基本认证(填入你的credentials),获取JSON响应 - 步骤3:添加
复制数据活动:源选择HTTP活动的输出,格式设为JSON;目标选择你的Azure SQL数据库,配置连接字符串并指定目标表 - 步骤4:配置字段映射,把JSON的每个字段对应到SQL表的列
- 步骤5:创建调度触发器,设置每月执行的时间(比如每月1号凌晨)
- 步骤6:发布管道并测试运行
关键注意事项
- 增量更新:不管用哪种方案,都要通过唯一标识(比如
ts_num+pl_date_last)或时间范围过滤,避免重复导入数据;如果API支持,可以只拉取上月新增的数据,提升效率 - 错误处理:添加异常捕获和日志记录,比如API请求失败、数据库连接超时的情况,必要时配置告警通知
- 性能优化:如果数据量很大,建议分批导入,避免一次性处理过多数据导致内存溢出或数据库超时
内容的提问来源于stack exchange,提问作者witchgen




