2017-01-11 4 views
1

В C# я использую SqlCommand ExecuteXmlReader() для вызова хранимой процедуры SQL Server, которая использует «для XML» для возврата больших (1gb +) сложных XML-файлов (несколько иерархии).XMLReader для XML-файла с использованием XMLWriter WriteNode - очень медленно для больших XML

ExecuteXmlReader() возвращает XmlReader, который я хочу сохранить в файле XML. Для этого я использую XmlWriter для передачи данных из XMLReader в файловую систему.

using (XmlReader xmlFromDatabase = xmlReaderFromDatabase) 
{ 
    var settings = new XmlWriterSettings {Encoding = Encoding.UTF8, Indent = true}; 
    using (XmlWriter outputXmlFileToDisk = XmlWriter.Create(fileDirectory + fileName, settings)) 
    { 
    outputXmlFileToDisk.WriteNode(xmlFromDatabase, false); 
    } 
} 

Side Примечание: Я не могу загрузить весь XML в память (XDocument), поскольку она слишком велика.

Моя проблема в том, что WriteNode очень медленный - для записи файла требуется несколько часов. Если я убью приложение, файл XML, записанный на диск, частично написан, поскольку файл передается по узлу по узлу.

Есть ли лучший способ сохранить XML быстрее с XmlReader, чем XMLWriter WriteNode?

(я знаю, что есть .ReadInnerXml(), но это возвращает строку, которая не подходит для размера XML)

После экспортировать файл необходимо преобразовать его (я могу использовать Saxon как .net framework не доказали, насколько я бы хотел, и схема проверила его через C#.

+2

Внутренне, данные XML передаются из SQL Server в виде потока символов (хотя внутренний класс '' SqlStream' и XmlSqlBinaryReader'). Таким образом, вы можете напрямую копировать поток в выходной поток, используя следующий способ: http://stackoverflow.com/questions/29672383/streaming-data-from-a-nvarcharmax-column-using-c-sharp (не пробовал, поэтому я не публикую это как ответ) – Lucero

+0

Кроме того, вы можете захотеть взглянуть на образец PrintXmlValuesViaNVarChar, который показывает горячую возможность использования потоковой и асинхронной поддержки XML-данных с помощью 'GetTextReader()' : https://msdn.microsoft.com/en-us/library/hh556234(v=vs.110).aspx – Lucero

+0

Гораздо быстрее сохранить инструменты SQL, чем инструменты C#. Посмотрите на SQLCMD.exe и BCP.exe. См. Https://msdn.microsoft.com/en-us/library/ms162816.aspx – jdweng

ответ

0

Я нашел решение, используя XmlReader/XMLWriter, кажется, хороший подход, чтобы взять (https://msdn.microsoft.com/en-us/library/ff647804.aspx) только что XMLWriter-WriteNode по умолчанию проверяет XML, как он пишет. Поскольку мы знаем, что XML, возвращаемый из SQL Server, является допустимым XML, и мы также XSD проверяем все XML перед отправкой, нам не нужно, чтобы сценарий выполнял проверку, когда он пишет. Передача объекта «Настройки» в XMLWriter с помощью CheckCharacters = false предотвращает избыточную проверку и выводит файл всего за несколько минут в зависимости от часов.

var settings = new XmlWriterSettings{ 
      CheckCharacters = false, 
      NewLineHandling = NewLineHandling.None, 
      Indent = true, 
      Encoding = Encoding.UTF8 }; 

using (var outputXmlFileToDisk = XmlWriter.Create(fileDirectory + fileName, settings)) 
{ 
Смежные вопросы