在 .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();
}