【问题标题】:Best way to import XML into a database C# .NET Core将 XML 导入数据库 C# .NET Core 的最佳方法
【发布时间】:2020-07-28 19:12:36
【问题描述】:

我正在从事一个项目,该项目要求我从我无法控制的 XML API 中获取数据并将该数据插入数据库(我控制)以供不同的应用程序使用(我控制但不能也修改代码吧)

我们已经设法通过提供者特殊端点从 XML API 获取完整的数据库布局,但所有其他查询(获取数据)都是通过 XML。

目前我所拥有的如下:

Book.cs - 这代表数据库表之一

using System;
using System.ComponentModel.DataAnnotations;

namespace Example.Models
{
    public partial class Book
    {
        [Key]
        public int Recordno { get; set; }
        public decimal? Amount { get; set; }
        public string Title { get; set; }
        public string Description { get; set; }
        public DateTime? Whenmodified { get; set; }
        public DateTime? Whencreated { get; set; }
        public int? Createdby { get; set; }
        public int? Modifiedby { get; set; }
    }
}

API Return XML - 这表示 API 返回的 XML(SDK 已经将其转换为 XMLDocument 类型)

<BOOKS>
   <BOOK>
      <RECORDNO>1</RECORDNO>
      <AMOUNT>24.12</AMOUNT>
      <TITLE>This is a title</TITLE>
      <DESCRIPTION>This is a description</DESCRIPTION>
      <WHENMODIFIED></WHENMODIFIED>
      <WHENCREATED>13/03/20 15:23:12</WHENCREATED>
      <CREATEDBY>3</CREATEDBY>
      <MODIFIEDBY></MODIFIEDBY>
   </BOOK>
   <BOOK>
      <RECORDNO>1</RECORDNO>
      <AMOUNT>24.12</AMOUNT>
      <TITLE>This is another title</TITLE>
      <DESCRIPTION>This is another description</DESCRIPTION>
      <WHENMODIFIED>21/03/20 12:45:23</WHENMODIFIED>
      <WHENCREATED>15/03/20 15:23:12</WHENCREATED>
      <CREATEDBY>6</CREATEDBY>
      <MODIFIEDBY>2</MODIFIEDBY>
   </BOOK>
</BOOKS>

目前我们这样做的方式是通过 switch 语句,但我希望有更好的方法。 部分 BookController.cs

var books = new List<Book>();

// response.Data return is a List<XElement>
foreach (var result in response.Data)
{
    var xElements = result.Elements();
    var book = new Book();
    foreach (var element in xElements)
    {
        switch (element.Name.ToString())
        {
            case "RECORDNO":
                book.Recordno = int.Parse(element.Value);
                break;
            case "AMOUNT":
                if (element.Value != string.Empty)
                {
                    book.Amount = int.Parse(element.Value);
                }
                break;
             // etc.
        }
    }
    books.Add(book);
}

我感觉有一种更简单的方法可以做到这一点,我只是不知道,我担心我有大约五十个表和数百个元素要做,这使得这种方法在时间上效率低下。

【问题讨论】:

    标签: c# sql xml .net-core


    【解决方案1】:

    使用xml序列化

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml;
    using System.Xml.Serialization;
    
    
    namespace ConsoleApplication8
    {
        class Program
        {
            const string FILENAME = @"c:\temp\test.xml";
            static void Main(string[] args)
            {
                XmlReader reader = XmlReader.Create(FILENAME);
                XmlSerializer serializer = new XmlSerializer(typeof(Books));
                Books books = (Books)serializer.Deserialize(reader);
    
    
            }
        }
        [XmlRoot("BOOKS")]
        public class Books
        {
            [XmlElement("BOOK")]
            public List<Book> books { get; set; }
        }
        public partial class Book
        {
            //[Key]
            [XmlElement("RECORDNO")]
            public int Recordno { get; set; }
            [XmlElement("AMOUNT")]
            public decimal? Amount { get; set; }
            [XmlElement("TITLE")]
            public string Title { get; set; }
            [XmlElement("DESCRIPTION")]
            public string Description { get; set; }
            private DateTime Whenmodified { get;set;}
            [XmlElement("WHENMODIFIED")]
            public string _Whenmodified {
                get { return Whenmodified.ToString("dd/MM/yy HH:mm:ss");  }
                set { DateTime.ParseExact(value,"dd/MM/yy HH:mm:ss", System.Globalization.CultureInfo.InvariantCulture);}
            }
            private DateTime Whencreated { get; set; }
            public string _Whencreated
            {
                get { return Whencreated.ToString("dd/MM/yy HH:mm:ss"); }
                set { DateTime.ParseExact(value, "dd/MM/yy HH:mm:ss", System.Globalization.CultureInfo.InvariantCulture); }
            }
            [XmlElement("CREATEDBY")]
            public int? Createdby { get; set; }
            [XmlElement("MODIFIEDBY")]
            public int? Modifiedby { get; set; }
        }
    
    
    }
    

    【讨论】:

    • 虽然这似乎工作得很好,但我收到有关 DateTime 字段的错误。 FormatException:字符串 '02/04/2020 18:04:05' 未被识别为有效的 DateTime。这是因为该值可以为空吗?我们可以做空日期时间吗?此外,如果 XML 中的整数值之一为 null(空值),则会遇到解析错误。
    • yer 是 4 位数字,代码仅使用两位数年份。
    • 无论如何要解决我遇到的 null int 错误(我更新了示例 XML 以反映几个字段中 null 的可能性)
    • 您没有 null int。您在解析数据时间时遇到问题。您可以修改我的获取/设置代码来处理不同的日期时间字符串。您可以使用 TryParseExact 或 ParseExact 可以有一个格式字符串数组来处理各种字符串格式。
    【解决方案2】:

    可以执行以下操作:

    1. 使用XML Schema Definition Tool (Xsd.exe) 生成类
    2. 使用生成的类来读取输入 XML
    3. 使用该数据

    【讨论】:

      【解决方案3】:

      欢迎来到 SO ?

      您在这里尝试从 XML 字符串表示构造内存中 C# 对象的操作称为 deserialization。这方面有很多资源(例如 MSDN),但here's 是一个指向 SO 帖子的链接,其中 OP 正在寻求实现类似的目标。

      应用到您上面的代码 sn-p 可能看起来像这样:

      var books = new List<Book>();
      
      var serializer = new XmlSerializer(typeof(Book));
      // response.Data return is a List<XElement>
      foreach (var result in response.Data)
      {
          var book = (Book)serializer.Deserialize(result.CreateReader());
          books.Add(book);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-06
        • 2011-02-19
        • 2018-05-21
        • 1970-01-01
        • 2015-08-16
        • 2011-10-09
        相关资源
        最近更新 更多