Это относится к проекту, который я наследую, и не могу изменить структуру таблицы или модель доступа к данным. Меня попросили оптимизировать алгоритм, используемый для вставки данных в базу данных.
У нас есть набор данных в таблице Т. Из этого мы выберем набор, который будем называть А. Мы также запросим XML-канал и получим набор, который будем называть X.
- Если значение из X находится в A, запись в должна быть обновлена, чтобы отражать данные для X.record
- Если значение из X не находится в A, X.record следует вставить в A
- Если значение из A не находится в X, A.record должен быть сохранен в A
- X должен быть полностью повторен для всех записей, а A должен быть обновлен.
Все эти изменения необходимо вставить обратно в базу данных.
Алгоритм, который настроен, выполняет следующие действия:
Query XML into a LIST
foreach over the XML LIST
look up foreach.item in A via LINQ (i.e. query = from record in A where
record.GUID == foreach.item.GUID
select record)
if query.Count() == 0
insert into A (via context.AddToTableName(newTableNameObject)
else
var currentRecord = query.First()
set all properties on currentRecord = properties from foreach.item
context.SaveChanges()
Я знаю, что это субоптимально. Я пытался получить A в объект (вызывать его queryA) вне цикла foreach, пытаясь переместить запрос в память и не попасть в диск, но, подумав об этом, я понял, что база данных уже находится в памяти.
Добавив объекты таймера в алгоритм, ясно, что наиболее затратным временем является вызов функции SaveChanges(). В некоторых случаях это 20 мс, а в некоторых других, объяснительно, он будет прыгать до 100 мс.
Я бы предпочел только один раз вызвать SaveChanges(). Я не могу понять, как это сделать, учитывая мою глубину знания EF (которая в лучшем случае тонкая) и ограничения неспособности изменить структуры таблиц и сохранить данные из A, которые не находятся в X.
Предложения?