将来自XML的数据存储在关系SQL数据库中

发布于 2025-01-17 12:43:31 字数 3061 浏览 2 评论 0原文

我需要将 XML 文件中的数据存储到带有 2 个表的 SQL 数据库中。 XML 文件如下所示(完整文件有更多 Document 节点):

<Documents>
    <Document>
        <Number>110</Number>
        <Date>2020-10-23</Date>
        <TotalPrice>3800</TotalPrice>
        <Items>
            <Item>
                <SKU>001234</SKU>
                <Name>FirstItem</Name>
                <Quantity>10</Quantity>
                <Price>1550</Price>
            </Item>
            <Item>
                <SKU>001235</SKU>
                <Name>SecondItem</Name>
                <Quantity>8</Quantity>
                <Price>1200</Price>
            </Item>
            <Item>
                <SKU>001236</SKU>
                <Name>ThirdItem</Name>
                <Quantity>21</Quantity>
                <Price>1050</Price>
            </Item>
        </Items>
    </Document>
</Documents>

SQL 数据库有 2 个表。一份用于文档,另一份用于项目。

create table Document(
DocumentId int identity(1,1) not null primary key,
Number int not null,
[Date] date not null,
TotalPrice money not null
);

create table Item(
ItemId int identity(1,1) not null primary key,
SKU int not null,
[Name] nvarchar(30) not null,
Quantity int not null,
Price money not null,
DocumentId int not null foreign key references Document(DocumentId)
);

以前,我只将简单的 XML 文件存储到只有一张表的 SQL 数据库中。我这样做的方式(假设我们只有文档表,我们可以忽略项目):

DocumentMetadata.cs

    [Serializable]
    [XmlRoot("Document")]
    public class DocumentMetadata
    {
        [XmlElement("Number")]
        public int Number { get; set; }

        [XmlElement("Date")]
        public DateTime Date { get; set; }

        [XmlElement("TotalPrice")]
        public int TotalPrice { get; set; }
    }

    [MetadataType(typeof(DocumentMetadata))]
    public partial class Document
    {

    }

Example.cs

XDocument xDoc = XDocument.Load(XmlFile);

List<Document> documentList = xDoc.Descendants("Document").Select(document => new Document
{
    Number = Convert.ToInt32(document.Element("Number").Value),
    Date = Convert.ToDateTime(document.Element("Date").Value),
    TotalPrice = Convert.ToInt32(document.Element("TotalPrice").Value),
}).ToList();


using (DocumentsEntities entity = new DocumentsEntities())
{
    foreach (var doc in documentList)
    {
        var dbDoc = entity.Documents.Where(x => x.Number.Equals(d.Number)).FirstOrDefault();

        if (dbDoc != null)
        {
            dbDoc.Number = doc.Number;
            dbDoc.Date = doc.Date;
            dbDoc.TotalPrice = doc.TotalPrice;
        }
        else
        {
            entity.Documents.Add(doc);
        }
    }
        entity.SaveChanges();
    }

因为我现在有一些更复杂的 XML 可以使用,还有 2 个相关的数据库表,我的头到处都是。在这种情况下最好的方法是什么?你能指出我正确的方向吗?提前致谢。

I need to store data from an XML file into SQL database with 2 tables. The XML file looks like this (the full file has more Document nodes):

<Documents>
    <Document>
        <Number>110</Number>
        <Date>2020-10-23</Date>
        <TotalPrice>3800</TotalPrice>
        <Items>
            <Item>
                <SKU>001234</SKU>
                <Name>FirstItem</Name>
                <Quantity>10</Quantity>
                <Price>1550</Price>
            </Item>
            <Item>
                <SKU>001235</SKU>
                <Name>SecondItem</Name>
                <Quantity>8</Quantity>
                <Price>1200</Price>
            </Item>
            <Item>
                <SKU>001236</SKU>
                <Name>ThirdItem</Name>
                <Quantity>21</Quantity>
                <Price>1050</Price>
            </Item>
        </Items>
    </Document>
</Documents>

The SQL database has 2 tables. One for Documents, and the other one for Items.

create table Document(
DocumentId int identity(1,1) not null primary key,
Number int not null,
[Date] date not null,
TotalPrice money not null
);

create table Item(
ItemId int identity(1,1) not null primary key,
SKU int not null,
[Name] nvarchar(30) not null,
Quantity int not null,
Price money not null,
DocumentId int not null foreign key references Document(DocumentId)
);

Previously, I've been storing only simple XML files into SQL databases with only one table. The way that I was doing it (let's say that we just have Document table, and we can ignore Items):

DocumentMetadata.cs

    [Serializable]
    [XmlRoot("Document")]
    public class DocumentMetadata
    {
        [XmlElement("Number")]
        public int Number { get; set; }

        [XmlElement("Date")]
        public DateTime Date { get; set; }

        [XmlElement("TotalPrice")]
        public int TotalPrice { get; set; }
    }

    [MetadataType(typeof(DocumentMetadata))]
    public partial class Document
    {

    }

Example.cs

XDocument xDoc = XDocument.Load(XmlFile);

List<Document> documentList = xDoc.Descendants("Document").Select(document => new Document
{
    Number = Convert.ToInt32(document.Element("Number").Value),
    Date = Convert.ToDateTime(document.Element("Date").Value),
    TotalPrice = Convert.ToInt32(document.Element("TotalPrice").Value),
}).ToList();


using (DocumentsEntities entity = new DocumentsEntities())
{
    foreach (var doc in documentList)
    {
        var dbDoc = entity.Documents.Where(x => x.Number.Equals(d.Number)).FirstOrDefault();

        if (dbDoc != null)
        {
            dbDoc.Number = doc.Number;
            dbDoc.Date = doc.Date;
            dbDoc.TotalPrice = doc.TotalPrice;
        }
        else
        {
            entity.Documents.Add(doc);
        }
    }
        entity.SaveChanges();
    }

Since I have a bit more complex XML now to work with, and 2 related database tables, my head is all over the place. What would be the best approach in this situation? Could you point me in the right direction? Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

只等公子 2025-01-24 12:43:31

我看不到使用复杂的C#代码切碎XML的要点。 SQL Server可以非常整齐地执行此操作,

INSERT Document
  (Number, [Date], TotalPrice)
SELECT
  x.doc.value('(Number/text())[1]','int'),
  x.doc.value('(Date/text())[1]','date'),
  x.doc.value('(TotalPrice/text())[1]','money')
FROM @xml.nodes('Documents/Document') x(doc);

INSERT Item
  (SKU, [Name], Quantity, Price, DocumentId)
SELECT
  x2.item.value('(SKU/text())[1]','int'),
  x2.item.value('(Name/text())[1]','nvarchar(30)'),
  x2.item.value('(Quantity/text())[1]','int')
  x2.item.value('(Price/text())[1]','money'),
FROM @xml.nodes('Documents/Document') x(doc)
JOIN Document d ON d.Number = x.doc.value('(Number/text())[1]','int')
CROSS APPLY x.doc.nodes('Item') x2(item);

您的C#代码可能是类似的,

const string sql = @"
THE ABOVE SQL
";

using (DocumentsEntities entity = new DocumentsEntities())
{
    entity.ExecuteSqlCommand(sql, new SqlParameter("@x", xDoc));
}

如果您需要IDENTITY ID号,可以使用outpation> outpation条款entity.fromsqlquery

I don't see the point in shredding the XML using complex C# code. SQL Server can do this pretty neatly

INSERT Document
  (Number, [Date], TotalPrice)
SELECT
  x.doc.value('(Number/text())[1]','int'),
  x.doc.value('(Date/text())[1]','date'),
  x.doc.value('(TotalPrice/text())[1]','money')
FROM @xml.nodes('Documents/Document') x(doc);

INSERT Item
  (SKU, [Name], Quantity, Price, DocumentId)
SELECT
  x2.item.value('(SKU/text())[1]','int'),
  x2.item.value('(Name/text())[1]','nvarchar(30)'),
  x2.item.value('(Quantity/text())[1]','int')
  x2.item.value('(Price/text())[1]','money'),
FROM @xml.nodes('Documents/Document') x(doc)
JOIN Document d ON d.Number = x.doc.value('(Number/text())[1]','int')
CROSS APPLY x.doc.nodes('Item') x2(item);

Your C# code could be something like

const string sql = @"
THE ABOVE SQL
";

using (DocumentsEntities entity = new DocumentsEntities())
{
    entity.ExecuteSqlCommand(sql, new SqlParameter("@x", xDoc));
}

If you need the IDENTITY ID numbers you can use an OUTPUT clause with entity.FromSqlQuery

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文