将XML类反序列化为一个类以写入数据库

时间:2019-04-29 11:18:07

标签: c# xml database entity-framework xml-deserialization

我正在尝试反序列化XML,并使用实体框架将结果保存到数据库中。

代码的第一部分只是从API获取所需的xml文件。 请参见下面:

    public static void Main()
    {
        Program semoAPI = new Program();

        using (WebClient webClient = new WebClient())
        {
            WebClient n = new WebClient();


            //Bid Ask Curves
            var bidAskCurves = n.DownloadString("https://reports.semopx.com/api/v1/documents/static-reports?" +
            "page=1&page_size=1&order_by=ASC&ReportName=Bid/Ask%20Curves&Group=Market%20Data");

            semoReports = JsonConvert.DeserializeObject<SemoReports>(bidAskCurves);

            Console.WriteLine("Bid Ask Curves Report: ");

            Console.WriteLine(semoReports.ResourceBaseUri + "/" + semoReports.Items[0].ResourceName);

            string bidAskCurvesXML = semoReports.ResourceBaseUri + "/" + semoReports.Items[0].ResourceName;

            XDocument bacDoc = XDocument.Load(bidAskCurvesXML);

            //Execute DeserializeBidAskCurves
            semoAPI.DeserializeBidAskCurves(bidAskCurvesXML);
        }
    }

下面是设置包含所需XML元素的类的方法:

namespace SEMO_app
{
    [XmlRoot("BidAskCurves")]
    public class BidAskCurves
    {
        [Key]
        public int ReportID { get; set; }

        [XmlElement("MarketArea")]
        public MarketArea[] MarketAreas{ get; set; }
    }

    public class MarketArea
    {
        public string MarketAreaName { get; set; }

        [XmlElement("DeliveryDay")]
        public DeliveryDay[] DeliveryDays { get; set; }
    }

    public class DeliveryDay
    {
        public string Day { get; set; }

        [XmlElement("TimeStep")]
        public TimeStep[] TimeSteps{ get; set; }
    }

    public class TimeStep
    {
        public string TimeStepID { get; set; }

        [XmlElement("Purchase")]
        public Purchase[] Purchases { get; set; }
    }

    public class Purchase
    {
        public string Price { get; set; }

        public string Volume { get; set; }
    }
} 

从这里开始,我想反序列化XML并将信息保存到数据库中,下面是我到目前为止拥有的代码,该代码反序列化XML,并在console.writesection中将结果重新显示好。

但是,我无法将这些值保存到数据库表中。代码会很好地执行并执行,并且数据库表会更新,但是该表仅包含一个报告ID列。我希望它包含console.write部分中列出的项目的位置。

        private void DeserializeBidAskCurves(string filename)
    {
        //Visual only not needed
        Console.WriteLine("\n" + "Reading BidAskCurves XML File");
        Console.WriteLine("===========================================================");

        // Create an instance of the XmlSerializer.
        XmlSerializer serializer = new XmlSerializer(typeof(BidAskCurves));

        // Declare an object variable of the type to be deserialized.
        BidAskCurves item;

        using (XmlReader reader = XmlReader.Create(filename))
        {
            // Call the Deserialize method to restore the object's state.
            item = (BidAskCurves)serializer.Deserialize(reader);

            //Write out the properties of the object. (Visual Only, not needed)
            Console.Write(
                item.MarketAreas[0].MarketAreaName + "\t" +
                item.MarketAreas[0].DeliveryDays[0].Day + "\t" +
                item.MarketAreas[0].DeliveryDays[0].TimeSteps[0].TimeStepID + "\t" +
                item.MarketAreas[0].DeliveryDays[0].TimeSteps[0].Purchases[0].Price + "\t" +
                item.MarketAreas[0].DeliveryDays[0].TimeSteps[0].Purchases[0].Volume);


            //write the properties to the db 
            using (SEMOContext context = new SEMOContext())
            {
                context.BidAskCurvesReports.Add(item);
                context.SaveChanges();
            }
        }
    }

链接到xml文件: https://reports.semopx.com/documents/BidAskCurves_NI-IDA3_20190401_20190401161933.xml

感谢您的任何帮助。

2 个答案:

答案 0 :(得分:0)

最初,很难知道实际上是什么问题?

但是访问

生成的URI之后
string bidAskCurvesXML = semoReports.ResourceBaseUri + "/" + semoReports.Items[0].ResourceName;

那就是https://reports.semopx.com/documents/BidAskCurves_NI-IDA3_20190401_20190401161933.xml

因此,您使用的类结构与URI生成的xml不同。

您需要为XML使用以下类结构

[XmlRoot("Purchase")]
public class Purchase
{
    [XmlElement("Price")]
    public string Price { get; set; }
    [XmlElement("Volume")]
    public string Volume { get; set; }
}

[XmlRoot("Sell")]
public class Sell
{
    [XmlElement("Price")]
    public string Price { get; set; }
    [XmlElement("Volume")]
    public string Volume { get; set; }
}

[XmlRoot("TimeStep")]
public class TimeStep
{
    [XmlElement("TimeStepID")]
    public string TimeStepID { get; set; }
    [XmlElement("Purchase")]
    public List<Purchase> Purchase { get; set; }
    [XmlElement("Sell")]
    public List<Sell> Sell { get; set; }
}

[XmlRoot("DeliveryDay")]
public class DeliveryDay
{
    [XmlElement("Day")]
    public string Day { get; set; }
    [XmlElement("TimeStep")]
    public List<TimeStep> TimeStep { get; set; }
}

[XmlRoot("MarketArea")]
public class MarketArea
{
    [XmlElement("MarketAreaName")]
    public string MarketAreaName { get; set; }
    [XmlElement("DeliveryDay")]
    public DeliveryDay DeliveryDay { get; set; }
}

[XmlRoot("BidAskCurves")]
public class BidAskCurves
{
    [XmlElement("MarketArea")]
    public MarketArea MarketArea { get; set; }
}

在将上述类结构与XmlSerializer结合使用之后,总共有12个时间戳可用

用法:

XmlSerializer serializer = new XmlSerializer(typeof(BidAskCurves));

BidAskCurves item;

using (XmlReader reader = XmlReader.Create("https://reports.semopx.com/documents/BidAskCurves_NI-IDA3_20190401_20190401161933.xml"))
{
    item = (BidAskCurves)serializer.Deserialize(reader);

    //Your code to add above parsed data into database.
}

输出:(来自调试器)

enter image description here

编辑1:

要先添加购买量和价格,然后添加销售量和价格,

...

item = (BidAskCurves)serializer.Deserialize(reader);

foreach (var ts in item.MarketArea.DeliveryDay.TimeStep)
{
    BidAskCurvesData bidAskCurvesData = new BidAskCurvesData
    {
        ReportID = 123,
        MarketAreaName = item.MarketArea.MarketAreaName,
        Day = item.MarketArea.DeliveryDay.Day,
        TimeSetID = ts.TimeStepID,
        PurchasePrice = ts.Purchase[0].Price,
        PurchaseVolume = ts.Purchase[0].Volume,
        SellPrice = ts.Sell[0].Price,
        SellVolume = ts.Sell[0].Volume
    };

    using (SEMOContext context = new SEMOContext())
    {
        context.BidAskCurvesReports.Add(item);
        context.SaveChanges();
    }
}

答案 1 :(得分:0)

    static void Main(string[] args)
    {
        using (WebClient webClient = new WebClient())
        {
            //Bid Ask Curves
            var bidAskCurves = webClient.DownloadString("https://reports.semopx.com/documents/BidAskCurves_NI-IDA3_20190401_20190401161933.xml");

            var serializer = new XmlSerializer(typeof(BidAskCurves));
            BidAskCurves result;

            using (TextReader reader = new StringReader(bidAskCurves))
            {
                // here it is
                result = (BidAskCurves)serializer.Deserialize(reader);
            }
        }

        Console.ReadKey();
    }

和xml对象:

[XmlRoot(ElementName = "Purchase")]
public class Purchase
{
    [XmlElement(ElementName = "Price")]
    public string Price { get; set; }
    [XmlElement(ElementName = "Volume")]
    public string Volume { get; set; }
}

[XmlRoot(ElementName = "Sell")]
public class Sell
{
    [XmlElement(ElementName = "Price")]
    public string Price { get; set; }
    [XmlElement(ElementName = "Volume")]
    public string Volume { get; set; }
}

[XmlRoot(ElementName = "TimeStep")]
public class TimeStep
{
    [XmlElement(ElementName = "TimeStepID")]
    public string TimeStepID { get; set; }
    [XmlElement(ElementName = "Purchase")]
    public List<Purchase> Purchase { get; set; }
    [XmlElement(ElementName = "Sell")]
    public List<Sell> Sell { get; set; }
}

[XmlRoot(ElementName = "DeliveryDay")]
public class DeliveryDay
{
    [XmlElement(ElementName = "Day")]
    public string Day { get; set; }
    [XmlElement(ElementName = "TimeStep")]
    public List<TimeStep> TimeStep { get; set; }
}

[XmlRoot(ElementName = "MarketArea")]
public class MarketArea
{
    [XmlElement(ElementName = "MarketAreaName")]
    public string MarketAreaName { get; set; }
    [XmlElement(ElementName = "DeliveryDay")]
    public DeliveryDay DeliveryDays { get; set; }
}

[XmlRoot(ElementName = "BidAskCurves")]
public class BidAskCurves
{
    [XmlElement(ElementName = "MarketArea")]
    public MarketArea MarketAreas { get; set; }
}

编辑

遍历结果:

foreach (var item in deliveryDays.TimeStep)
{
    // var day = deliveryDays.Day
    var timeStep_Purchase = item.Purchase;
    var timeStep_Sell = item.Sell;
    var timeStep_Id = item.TimeStepID;
}