Это относится к проекту, который я наследую, и не может изменить структуру таблицы или модель доступа к данным.Меня попросили оптимизировать алгоритм, используемый для вставки данных в базу данных.
У нас есть набор данных в таблице T. Из этого мы извлекаем набор, который будем называть A. Мы также запрашиваем канал XML иполучить набор, который мы назовем X.
- Если значение из X находится в A, запись в 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.
Предложения?