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



我需要将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
{
}

示例.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个相关的数据库表,所以我的脑子里到处都是。在这种情况下,最好的方法是什么?你能给我指正确的方向吗?提前谢谢。

我不认为使用复杂的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));
}

如果您需要IDENTITYID号,您可以使用带有entity.FromSqlQueryOUTPUT子句

最新更新