微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何将数据从外部API存储到我的MS SQL数据库中

如何解决如何将数据从外部API存储到我的MS SQL数据库中

我正在尝试从外部API提取数据,并使用实体框架将此数据保存在MS sql数据库中。我是实体框架的新手,无法弄清楚如何使数据持久化。根据以下模型,遵循“代码优先”原则创建数据库

JsonResponse.cs

public partial class JsonResponse
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int Id { get; set; }
    [JsonProperty("prtg-version")]
    public string PrtgVersion { get; set; }
    [JsonProperty("treesize")]
    public int TreeSize { get; set; }
    [JsonProperty("devices")]
    public Devices[] devices { get; set; }
}

public partial class Devices
{
    [Key]
    [JsonProperty("objid")]
    public int objid { get; set; }
    [JsonProperty("probe")]
    public string probe { get; set; }
    [JsonProperty("device")]
    public string device { get; set; }
    [JsonProperty("host")]
    public string host { get; set; }
}

我设法从JSON中的API成功接收了数据,将其反序列化并将其添加List <JsonResponse> dataG中。现在,我希望通过将其保存到EF数据库来使这些数据持久化。由于我的JsonResponse包含Devices对象的列表,因此我在如何做到这一点上苦苦挣扎。我从外部API中提取数据的控制器如下所示:

CMDBController.cs

public class CMDBController : Controller
{
    private DbContext db = new DbContext();

    public async Task<ActionResult> test()
    {
        List<JsonResponse> dataG = new List<JsonResponse>();
        using (var httpClient = new HttpClient())
        {
            using (var response = await httpClient
                .GetAsync(
                    "/api/table.json?content=devices&output=json&columns=objid,probe,group,device,host")
            )
            {
                string apiResponse = await response.Content.ReadAsstringAsync();
                var data = JsonConvert.DeserializeObject<JsonResponse>(apiResponse);
                dataG.Add(data);
                var devices = data.devices;

                foreach (var item in devices)
                {
                    db.Add(item);
                    db.SaveChanges();
                }
            }
        }
        return View(dataG);
    }

API的JSON数据如下:

{
prtg-version: "20.4.63.1412",treesize: 2,devices: [
{
objid: 40,probe: "Local Probe",group: "Local Probe",device: "Probe Device",host: "127.0.0.1"
},{
objid: 42,group: "Network Infrastructure",device: "DNS: 84.116.46.23",host: "84.116.46.23"
}

DBContext

public class FrontDbContext : DbContext
{
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UsesqlServer(
            "Server=(localdb)\\MSsqlLocalDB;Database=FrontDB;MultipleActiveResultSets=true");
    }

    public DbSet<JsonResponse> Responses { get; set; }
}

}

编辑1

public class CMDBController : Controller
{
    private DbContext db = new DbContext();

    public async Task<ActionResult> test()
    {
        List<JsonResponse> dataG = new List<JsonResponse>();
        using (var httpClient = new HttpClient())
        {
            using (var response = await httpClient
                .GetAsync(
                    "/api/table.json?content=devices&output=json&columns=objid,host")
            )
            {
                string apiResponse = await response.Content.ReadAsstringAsync();
                var data = JsonConvert.DeserializeObject<JsonResponse>(apiResponse);
                dataG.Add(data);
                var devices = data.devices;
                db.Responses.AddRange(data);
                db.SaveChanges();
            }
        }
        return View(dataG);
    }

解决方法

您好,这是我的第一个答案,我正在学习英语,我会尝试做得更好。

您有两个桌子吗?掌握细节?

我建议您首先组织代码并分离职责,首先需要具有Dto Object来表示JSON对象以及将数据插入数据库中的实体,然后分离方法,但是我将与您当前的实体共享解决方案

首先,您需要具有包含实体和连接字符串的DbContext,并带有EntityFrameworkCore的DbContext示例:

public class MyDbContext:DbContext
    {
        private readonly string connectionString;

        public MyDbContext(string connectionString)
        {
            this.connectionString = connectionString;
            _migrateDatabase = true;
        }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            base.OnConfiguring(optionsBuilder);
            optionsBuilder.UseMySql(connectionString);
        }

        public DbSet<JsonResponse> JsonResponses { get; set; }
        public DbSet<Devices> Devices { get; set; }
    }

如果您具有主要详细信息,则需要使用外键创建导航属性,在这种情况下,我将在Device实体中创建此属性。

public partial class JsonResponse
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int Id { get; set; }
    [JsonProperty("prtg-version")]
    public string PrtgVersion { get; set; }
    [JsonProperty("treesize")]
    public int TreeSize { get; set; }

    [JsonProperty("devices")]
    public List<Devices> devices { get; set; }
}

public partial class Devices
{
    [Key]
    [JsonProperty("objid")]
    public int objid { get; set; }
    [JsonProperty("probe")]
    public string probe { get; set; }
    [JsonProperty("device")]
    public string device { get; set; }
    [JsonProperty("host")]
    public string host { get; set; }

    public int JsonResponseId { get; set; }
    
    [ForeignKey("JsonResponseId")]
    public JsonResponse JsonResponse { get; set; }
}

要保存数据,您需要添加主体实体,详细信息将自动保存:

public class CMDBController : Controller
{
    private MyDbContext db = new MyDbContext("mycnn");

    public async Task<ActionResult> Test()
    {
        JsonResponse data = GetJsonData();
        db.JsonResponses.Add(data);
        db.SaveChanges();
        return View(data);
    }

    JsonResponse GetJsonData(){
         using (var httpClient = new HttpClient())
        {
          var response = await httpClient.GetAsync(
                    "/api/table.json?content=devices&output=json&columns=objid,probe,group,device,host");
          string apiResponse = await response.Content.ReadAsStringAsync();
          return JsonConvert.DeserializeObject<JsonResponse>(apiResponse);
        }
    }
}

如果您没有主要详细信息,并且需要保存一系列数据,则必须使用AddRange,并将所有数据保存在一个操作中:

public async Task<ActionResult> Test()
    {
        JsonResponse data = GetJsonData();
        db.Devices.AddRange(data.Devices);
        db.SaveChanges();
        return View(data);
    }
,

正如marc_s所说,EF核心支持访问许多不同的数据库,您使用的是哪种数据库?

通常,要通过EF核心将新数据插入数据库,可以使用DbContext.Add方法或DbContext.AddRange方法添加新项目。您可以查看以下文章:EF core Saving data

我假设您使用的是MS SQL Server数据库,根据您的描述,JsonResponseDevices对象包含one-to-Many relationship,因此您可以使用导航属性,而不是Devices[],请尝试如下更改代码:

public partial class JsonResponse
{
    [Key] 
    public int Id { get; set; }
    [JsonProperty("prtg-version")]
    public string PrtgVersion { get; set; }
    [JsonProperty("treesize")]
    public int TreeSize { get; set; }
    [JsonProperty("devices")]
    public List<Devices> devices { get; set; }
}

public partial class Devices
{
    [Key()]
    [DatabaseGenerated(DatabaseGeneratedOption.None)] // prevent database auto generate objid.
    [JsonProperty("objid")]
    public int objid { get; set; }
    [JsonProperty("probe")]
    public string probe { get; set; }
    [JsonProperty("device")]
    public string device { get; set; }
    [JsonProperty("host")]
    public string host { get; set; }
}

然后,在迁移并在数据库中生成相关表之后,您可以参考以下代码将新项目插入数据库:

    private readonly ILogger<HomeController> _logger;
    private readonly WebApplication2Context _dbcontext;

    public HomeController(ILogger<HomeController> logger,WebApplication2Context context)
    {
        _logger = logger;
        _dbcontext = context;
    }

    public IActionResult Index()
    {
        List<JsonResponse> data = new List<JsonResponse>()
        {
            new JsonResponse(){ PrtgVersion ="20.4.63.1412",TreeSize = 2,devices = new List<Devices>()
            {
                new Devices(){ objid= 40,probe="Local Probe",device = "Probe Device",host = "127.0.0.1"},new Devices(){ objid= 41,device = "DNS: 84.116.46.23",host = "86.114.46.23"}
            }
            }
        };
        _dbcontext.JsonResponses.AddRange(data);
        _dbcontext.SaveChanges();
        return View();
    }

注释:由于JsonResponse对象和Devices对象包含一对多关系,因此在使用上述代码插入新的JsonResponse时,它将自动插入相关的{{ 1}}对象放入“设备”表中。有关更多详细信息,请检查Saving Related Data

此外,您还可以使用以下代码将新设备添加到“设备”表中:

Devices

参考:Entity Framework Core One To Many Relationships Conventions

Navigation Properties

,
Update the DbContextClass


public class MyDbContext:DbContext
{
    private readonly string connectionString;

    public MyDbContext(string connectionString)
    {
        this.connectionString = connectionString;
        _migrateDatabase = true;
    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        base.OnConfiguring(optionsBuilder);
        optionsBuilder.UseMySql(connectionString);
    }

    public DbSet<JsonResponse> JsonResponses { get; set; }
}

更新控制器

public async Task<ActionResult> Test()
{        
    using (var httpClient = new HttpClient())
    {
        using (var response = await httpClient
            .GetAsync(
                "/api/table.json?content=devices&output=json&columns=objid,host")
        )
        {
            string apiResponse = await response.Content.ReadAsStringAsync();
            var data = JsonConvert.DeserializeObject<JsonResponse>(apiResponse);
            db.JsonResponses.Add(data);
            db.SaveChang();
        }
    }
    return View(dataG);
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。