在 .NET 中将 really-large collection 转换为 Xml
Convert a really-large collection to Xml in .NET
我有一个很大的数据库结果(作为项目列表)。返回 450,000 件商品。
然后我使用 Linq-To-Xml 将此 collection 转换为 XDocument
。它有效 - 但它是一个巨大的内存命中。
是否可以立即将 collection 项目转换为 XML 但不是全部在内存中..而是在对话发生时流式传输到文件?
XML数据最终以超过1Gig的速度保存到磁盘。因此可以公平地假设内存消耗 至少 是这样。
那么 - 有没有一种方法可以将 XML 段流式传输到磁盘,因为我们遍历列表中的每个项目 而不是 转换整个 result-set 到 InMemory XDocument
然后将其保存到磁盘?
注意:请不要提出将列表分成更小的部分等建议。我理解,但我已经排除了这种可能性。
这是我正在做的一些示例代码(以帮助您了解想法)。
// Create the xml doc.
var elements = from user in userResults
select new XElement("user",
new XElement("id", user.Id),
.....<snip>...... );
return new XDocument(new XDeclaration("1.0", "utf-8", "yes"),
new XElement("users", elements));
// Save the doc to the filesystem.
using (var writer = _fileSystemWrapper.CreateText(destinationXmlFileName))
{
xmldDocument.Save(writer);
}
更新
也许还有一些其他的技巧,比如使用 Linq-To-Xml 以 10 个为一组创建元素段......并且对于每 10 个,将其附加到文件末尾?
您可以使用 XStreamingElement。不过,它需要一些小的重构,主要不是创建 XDocument
和使用不同的 Save
方法。
下面是与您的示例相对应的示例,仅供您参考:
var elements = from user in userResults
select new XElement("user",
new XElement("id", user.Id),
.....<snip>...... );
var content = new XStreamingElement("users", elements);
using (var output = _fileSystemWrapper.CreateText(destinationXmlFileName))
using (var writer = XmlWriter.Create(output, new XmlWriterSettings { Encoding = Encoding.UTF8, Indent = true })
{
// Use the next line if you don't require standalone="yes" attribute
// content.Save(writer);
writer.WriteStartDocument(true);
content.WriteTo(writer);
writer.WriteEndDocument();
}
我有一个很大的数据库结果(作为项目列表)。返回 450,000 件商品。
然后我使用 Linq-To-Xml 将此 collection 转换为 XDocument
。它有效 - 但它是一个巨大的内存命中。
是否可以立即将 collection 项目转换为 XML 但不是全部在内存中..而是在对话发生时流式传输到文件?
XML数据最终以超过1Gig的速度保存到磁盘。因此可以公平地假设内存消耗 至少 是这样。
那么 - 有没有一种方法可以将 XML 段流式传输到磁盘,因为我们遍历列表中的每个项目 而不是 转换整个 result-set 到 InMemory XDocument
然后将其保存到磁盘?
注意:请不要提出将列表分成更小的部分等建议。我理解,但我已经排除了这种可能性。
这是我正在做的一些示例代码(以帮助您了解想法)。
// Create the xml doc.
var elements = from user in userResults
select new XElement("user",
new XElement("id", user.Id),
.....<snip>...... );
return new XDocument(new XDeclaration("1.0", "utf-8", "yes"),
new XElement("users", elements));
// Save the doc to the filesystem.
using (var writer = _fileSystemWrapper.CreateText(destinationXmlFileName))
{
xmldDocument.Save(writer);
}
更新
也许还有一些其他的技巧,比如使用 Linq-To-Xml 以 10 个为一组创建元素段......并且对于每 10 个,将其附加到文件末尾?
您可以使用 XStreamingElement。不过,它需要一些小的重构,主要不是创建 XDocument
和使用不同的 Save
方法。
下面是与您的示例相对应的示例,仅供您参考:
var elements = from user in userResults
select new XElement("user",
new XElement("id", user.Id),
.....<snip>...... );
var content = new XStreamingElement("users", elements);
using (var output = _fileSystemWrapper.CreateText(destinationXmlFileName))
using (var writer = XmlWriter.Create(output, new XmlWriterSettings { Encoding = Encoding.UTF8, Indent = true })
{
// Use the next line if you don't require standalone="yes" attribute
// content.Save(writer);
writer.WriteStartDocument(true);
content.WriteTo(writer);
writer.WriteEndDocument();
}