#c# #entity-framework #linq-to-entities #linq-to-xml
#c# #entity-framework #linq-to-entities #linq-to-xml
Вопрос:
Я создал приложение, которое генерирует большой XML-файл с использованием Linq-to-Entities и XElement. Это занимает целое ядро нашего сервера с частотой 2 ГГц примерно полчаса и использует ~ 1 ГБ памяти.
Я выполняю следующий тип работы:
var xml = from x in dbContext.Table1
select new XElement("Table1",
new XElement("Field1", x.Field1),
new XElement("Field2", x.Field2),
new XElement("Field3", x.Field3),
new XElement("MoreFields",
new XElement("FieldA", x.MoreFields.FieldA),
new XElement("FieldA", x.MoreFields.FieldA),
new XElement("FieldA", x.MoreFields.FieldA.DoSomeWorkWithThisField())
)
);
У меня есть еще один или два уровня глубины, и в нескольких полях выполняется работа, например, синтаксический int
анализ строки с использованием RegEx.Match()
Есть ли у кого-нибудь какие-либо рекомендации по оптимизации или рефакторингу? Я пытался использовать XStreamingElement
, но, похоже, это не имело никакого значения.
Комментарии:
1. Я думаю, что проблема здесь, скорее всего, связана с тем, как вы используете dbcontext. Это рабочий код? Является ли Table1
IQueryable<OfSomething>
. Мне это не кажется правильным.2. Вы правы, я это исправлю. Исправлено
Ответ №1:
Похоже, вы извлекаете все Table1
несколько раз.
Можете ли вы извлечь его в a List<T>
, а затем использовать его повторно?
var list = dbContext.Table1.ToList();
var xml = new XElement("Table1",
new XElement("Field1", list.Field1),
new XElement("Field2", list.Field2),
new XElement("Field3", list.Field3),
new XElement("MoreFields",
new XElement("FieldA", list.MoreFields.FieldA),
new XElement("FieldA", list.MoreFields.FieldA),
new XElement("FieldA", list.MoreFields.FieldA.DoSomeWorkWithThisField())
)
);
Я подозреваю, что это гораздо сложнее, но в основном — извлеките то, что вам нужно, в память заранее, а затем работайте с этим. Если вам нужно использовать элемент данных только один раз, это можно делать только тогда, когда вам это нужно, но избегайте повторного извлечения одних и тех же данных снова и снова.
Насколько велик документ, который вы создаете, и сколько памяти занимает ваш компьютер? Возможно, вы захотите попробовать посмотреть на счетчики производительности — возможно, вы тратите большую часть времени на сбор мусора.
Комментарии:
1. Спасибо. Я попробую это завтра. У меня сложилось впечатление, что Linq-to-Entities поймет, что я ссылаюсь на одну и ту же таблицу несколько раз, когда она создает операторы SQL. Знаете ли вы какой-нибудь хороший материал для чтения по использованию Linq-to-Entities для генерации
XElements
?
Ответ №2:
Для больших документов вам следует рассмотреть потоковое решение, например XmlWriter
, вместо решения, подобного XDocument
которому, все данные хранятся в памяти.