[英]Store data from XML in relational SQL database
I need to store data from an XML file into SQL database with 2 tables.我需要将 XML 文件中的数据存储到具有 2 个表的 SQL 数据库中。 The XML file looks like this (the full file has more Document
nodes): 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>
The SQL database has 2 tables. SQL 数据库有 2 个表。 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.以前,我只将简单的 XML 个文件存储到只有一个表的 SQL 个数据库中。 The way that I was doing it (let's say that we just have Document table, and we can ignore Items):我这样做的方式(假设我们只有文档表,我们可以忽略项目):
DocumentMetadata.cs文档元数据.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例子.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.由于我现在要使用更复杂的 XML 和 2 个相关的数据库表,所以我的脑袋到处都是。 What would be the best approach in this situation?在这种情况下最好的方法是什么? Could you point me in the right direction?你能指出我正确的方向吗? Thanks in advance.提前致谢。
I don't see the point in shredding the XML using complex C# code.我看不出使用复杂的 C# 代码粉碎 XML 有什么意义。 SQL Server can do this pretty neatly SQL 服务器可以很巧妙地做到这一点
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您的 C# 代码可能类似于
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
如果您需要IDENTITY
ID 号码,您可以将OUTPUT
子句与entity.FromSqlQuery
一起使用
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.