You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用C#(.NET) Azure Functions实现API数据直导SQL数据库?

兄弟,我来给你捋清楚怎么用C#/.NET直接把REST API返回的大量JSON数据怼进SQL数据库——你已经有API取数和Azure Functions写库的基础,其实就是把这俩的核心逻辑捏到一起,重点是针对大数据量做性能和稳定性优化,直接上干货:

核心思路

跳过Web服务中转,直接在C#程序(或Azure Functions)里完成「API请求→JSON解析→批量写入SQL」的闭环,核心是避免逐条插入,用高效的批量写入方案处理大数据量。

具体步骤与代码示例

1. 先装必要的NuGet包

这几个是刚需:

  • System.Net.Http:发送API请求
  • System.Text.Json(或Newtonsoft.Json):JSON反序列化(原生库轻量,Newtonsoft兼容性更强,选你顺手的)
  • Microsoft.Data.SqlClient:操作SQL数据库(比旧版System.Data.SqlClient更推荐,支持最新SQL特性)

2. 把API返回的JSON映射成C#实体

先定义和API返回结构匹配的实体类,比如API返回的是用户列表:

// 假设API返回格式:{"data": [{"id":1,"name":"张三","email":"zhangsan@example.com"},...]}
public class ApiResponse<T>
{
    public List<T> Data { get; set; }
}

public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
}

3. 从API拉取数据(流式处理省内存)

大数据量别一次性把所有JSON加载到内存,用流式读取+反序列化:

public async Task<ApiResponse<User>> FetchApiDataAsync(string apiUrl)
{
    using var httpClient = new HttpClient();
    // 加API认证头,比如Bearer Token
    httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer YourApiToken");
    
    // 流式读取API响应,避免内存爆了
    using var stream = await httpClient.GetStreamAsync(apiUrl);
    var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
    return await JsonSerializer.DeserializeAsync<ApiResponse<User>>(stream, options);
}

4. 批量写入SQL(重点!别逐条Insert)

针对大数据量,推荐两种方案:

方案一:SqlBulkCopy(性能天花板,超大量数据首选)

public async Task BulkInsertUsersAsync(List<User> users, string connectionString)
{
    // 把List转成DataTable(SqlBulkCopy支持的格式)
    var dataTable = new DataTable();
    dataTable.Columns.Add("Id", typeof(int));
    dataTable.Columns.Add("Name", typeof(string));
    dataTable.Columns.Add("Email", typeof(string));

    foreach (var user in users)
    {
        dataTable.Rows.Add(user.Id, user.Name, user.Email);
    }

    using var connection = new SqlConnection(connectionString);
    await connection.OpenAsync();

    using var bulkCopy = new SqlBulkCopy(connection)
    {
        DestinationTableName = "Users", // 目标SQL表名
        BatchSize = 1000 // 每批插入的数量,根据数据库性能调整
    };

    // 列映射(如果实体和SQL列名完全一致可以省略)
    bulkCopy.ColumnMappings.Add("Id", "UserId"); // 比如SQL列名是UserId,实体是Id
    bulkCopy.ColumnMappings.Add("Name", "UserName");
    bulkCopy.ColumnMappings.Add("Email", "UserEmail");

    await bulkCopy.WriteToServerAsync(dataTable);
}

方案二:Table-Valued Parameters(TVP,中等数据量更灵活)

先在SQL里定义自定义表类型:

CREATE TYPE UserTableType AS TABLE
(
    UserId INT,
    UserName NVARCHAR(50),
    UserEmail NVARCHAR(100)
);

然后C#代码调用:

public async Task InsertUsersWithTvpAsync(List<User> users, string connectionString)
{
    var tvp = new DataTable();
    tvp.Columns.Add("UserId", typeof(int));
    tvp.Columns.Add("UserName", typeof(string));
    tvp.Columns.Add("UserEmail", typeof(string));

    foreach (var user in users)
    {
        tvp.Rows.Add(user.Id, user.Name, user.Email);
    }

    using var connection = new SqlConnection(connectionString);
    await connection.OpenAsync();

    using var command = new SqlCommand(
        "INSERT INTO Users (UserId, UserName, UserEmail) SELECT UserId, UserName, UserEmail FROM @UserTable", 
        connection
    );
    command.Parameters.Add(new SqlParameter("@UserTable", SqlDbType.Structured)
    {
        TypeName = "UserTableType",
        Value = tvp
    });

    await command.ExecuteNonQueryAsync();
}

5. 整合到Azure Functions(或控制台程序)

如果用Azure Functions,直接把逻辑塞进去,比如定时触发同步:

public class ApiToSqlSyncFunction
{
    private readonly IConfiguration _configuration;

    public ApiToSqlSyncFunction(IConfiguration configuration)
    {
        _configuration = configuration;
    }

    [FunctionName("ApiToSqlSync")]
    public async Task Run([TimerTrigger("0 0 2 * * *")] TimerInfo myTimer, ILogger log)
    {
        log.LogInformation("Starting API to SQL sync job");

        var apiUrl = _configuration["ApiSettings:Url"];
        var connectionString = _configuration["ConnectionStrings:SqlDb"];

        // 1. 拉取API数据
        var apiResponse = await FetchApiDataAsync(apiUrl);
        if (apiResponse?.Data == null || !apiResponse.Data.Any())
        {
            log.LogWarning("No data fetched from API");
            return;
        }

        // 2. 批量写入SQL
        await BulkInsertUsersAsync(apiResponse.Data, connectionString);

        log.LogInformation($"Successfully inserted {apiResponse.Data.Count} records into SQL");
    }

    // 把上面的FetchApiDataAsync和BulkInsertUsersAsync方法放这里
}
大数据量额外优化建议
  • 分批请求API:如果API支持分页(比如page、pageSize参数),别一次性拉全量,分批次请求+写入,避免内存溢出。
  • 流式边读边写:如果数据大到连DataTable都装不下,可以用IDataReader配合SqlBulkCopy,边读API数据流边写SQL,完全不占内存。
  • 事务保护:用SqlTransaction包裹写入逻辑,失败时回滚,保证数据一致性。
  • 临时禁用索引:写入前禁用SQL表的非聚集索引,写完再重建,能大幅提升写入速度。
  • 错误重试:用Polly库加重试逻辑,处理API超时、SQL写入失败的情况,保证任务稳定性。

内容的提问来源于stack exchange,提问作者adlisval

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 09:19:25