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

ASP.NET Core 3.1中如何将Web API数据通过EF Core存入SQL Server数据库

解决思路

你的问题核心是接口返回的DTO类型和EF Core数据库实体类型不匹配,无法直接传入EF的新增方法,只需要完成DTO到数据库实体的字段映射,再调用EF的保存逻辑即可。


实现步骤

1. 修正反序列化类型

你现有拉取代码里JsonConvert.DeserializeObject<Crypto>(result)的泛型类型需要调整为你定义的Root类,才能正确匹配接口返回的JSON结构。

2. 完善数据库实体设计

以下是符合EF Core规范的实体示例,你可以直接复用或根据业务调整:

// 加密货币主实体
public class CryptoCurrency
{
    // 主键可直接用CoinMarketCap返回的币ID,也可以设置为自增主键,单独加CmcId字段存储接口返回的ID
    public int Id { get; set; }
    public string Name { get; set; }
    public string Symbol { get; set; }
    public string Slug { get; set; }
    public int NumMarketPairs { get; set; }
    public DateTime DateAdded { get; set; }
    // 字符串类型存储标签的JSON序列化结果
    public string Tags { get; set; }
    public long? MaxSupply { get; set; }
    public double CirculatingSupply { get; set; }
    public double TotalSupply { get; set; }
    public int CmcRank { get; set; }
    public DateTime LastUpdated { get; set; }
    // 记录本次数据同步时间
    public DateTime SyncTime { get; set; } = DateTime.Now;
    // 导航属性:关联平台信息
    public PlatformEntity Platform { get; set; }
    // 导航属性:关联USD报价
    public UsdQuote UsdQuote { get; set; }
}

// 平台信息实体
public class PlatformEntity
{
    public int Id { get; set; }
    public int CmcPlatformId { get; set; }
    public string Name { get; set; }
    public string Symbol { get; set; }
    public string Slug { get; set; }
    public string TokenAddress { get; set; }
    // 外键关联加密货币
    public int CryptoCurrencyId { get; set; }
    public CryptoCurrency CryptoCurrency { get; set; }
}

// USD报价实体
public class UsdQuote
{
    public int Id { get; set; }
    public double Price { get; set; }
    public double Volume24h { get; set; }
    public double PercentChange1h { get; set; }
    public double PercentChange24h { get; set; }
    public double PercentChange7d { get; set; }
    public double PercentChange30d { get; set; }
    public double PercentChange60d { get; set; }
    public double PercentChange90d { get; set; }
    public double MarketCap { get; set; }
    public DateTime LastUpdated { get; set; }
    // 外键关联加密货币
    public int CryptoCurrencyId { get; set; }
    public CryptoCurrency CryptoCurrency { get; set; }
}

修改完实体后重新生成迁移更新数据库即可。

3. 编写DTO到实体的映射逻辑

可以直接手动写映射方法(不需要额外依赖,适合新手),也可以用AutoMapper等映射工具:

public static class DtoToEntityMapper
{
    public static CryptoCurrency MapToCryptoEntity(Datum dto)
    {
        var entity = new CryptoCurrency
        {
            Id = dto.Id,
            Name = dto.Name,
            Symbol = dto.Symbol,
            Slug = dto.Slug,
            NumMarketPairs = dto.Num_market_pairs,
            DateAdded = dto.Date_added,
            Tags = JsonConvert.SerializeObject(dto.Tags),
            MaxSupply = dto.Max_supply,
            CirculatingSupply = dto.Circulating_supply,
            TotalSupply = dto.Total_supply,
            CmcRank = dto.Cmc_rank,
            LastUpdated = dto.Last_updated
        };

        // 映射平台信息
        if (dto.Platform != null)
        {
            entity.Platform = new PlatformEntity
            {
                CmcPlatformId = dto.Platform.Id,
                Name = dto.Platform.Name,
                Symbol = dto.Platform.Symbol,
                Slug = dto.Platform.Slug,
                TokenAddress = dto.Platform.Token_address
            };
        }

        // 映射USD报价
        if (dto.Quote?.USD != null)
        {
            entity.UsdQuote = new UsdQuote
            {
                Price = dto.Quote.USD.Price,
                Volume24h = dto.Quote.USD.Volume_24h,
                PercentChange1h = dto.Quote.USD.Percent_change_1h,
                PercentChange24h = dto.Quote.USD.Percent_change_24h,
                PercentChange7d = dto.Quote.USD.Percent_change_7d,
                PercentChange30d = dto.Quote.USD.Percent_change_30d,
                PercentChange60d = dto.Quote.USD.Percent_change_60d,
                PercentChange90d = dto.Quote.USD.Percent_change_90d,
                MarketCap = dto.Quote.USD.Market_cap,
                LastUpdated = dto.Quote.USD.Last_updated
            };
        }
        return entity;
    }
}

4. 编写保存逻辑

// 1. 拉取接口数据
var cmcClient = new MyClass();
var cmcResult = await cmcClient.GetData();
if (cmcResult?.Data == null || !cmcResult.Data.Any())
{
    return;
}

// 2. 批量转换DTO为数据库实体
var entityList = cmcResult.Data.Select(DtoToEntityMapper.MapToCryptoEntity).ToList();

// 3. 批量插入到数据库
await context.CryptoCurrencies.AddRangeAsync(entityList);
await context.SaveChangesAsync();

可选优化建议

  • 如果需要保留历史报价数据,每次拉取直接新增即可;如果只需要最新数据,可以先根据Cmc的币ID查询库中已有数据,存在则更新、不存在则新增。
  • 不要每次请求都新建HttpClient,建议注入IHttpClientFactory创建实例,避免端口耗尽问题。
  • 数据量较大时建议分批插入,不要一次提交上千条数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.14 14:54:01