Лучший способ обновить коллекцию данных SQL

Просто используйте обычное распознавание списка

>>> abc = [(1531,), (4325,), (9204,)]
>>> dfg = [val for items in abc for val in items]
>>> dfg
[1531, 4325, 9204]

Если размер результата запроса слишком велик, используйте itertools.chain

>>> from itertools import chain
>>> list(chain(*abc))
[1531, 4325, 9204]
0
задан camus 19 January 2019 в 23:41
поделиться

1 ответ

Итак, у вас есть элемент пользовательского интерфейса, заполненный элементами некоторого класса. У вас также есть база данных с таблицей, заполненной предметами того же класса.

IEnumerable<MyClass> userInterfaceElements = ...
IQueryable<MyClass> databaseElements = ...

Примечание: запрос еще не выполнен!

Вы хотите обновить базу данных так, чтобы после обновления ваша база данных содержала элементы из ваших элементов пользовательского интерфейса.

  • Элементы пользовательского интерфейса, которых еще нет в базе данных, будут добавлены
  • Элементы базы данных, которых нет в пользовательском интерфейсе, должны быть удалены
  • Элементы пользовательского интерфейса которые также в базе данных должны быть обновлены.

Вы не писали, как решаете, есть ли элемент пользовательского интерфейса в базе данных. Предположим, вы не изобретаете первичные ключи. Это означает, что элементы со значением по умолчанию (ноль) для вашего первичного ключа являются элементами, которых нет в базе данных.

var itemsToAdd = userInterfaceElements.Where(row => row.Id == 0);
var itemsToUpdate = userInterfaceElements.Where(row => row.Id != 0);

var idsItemsToKeep = itemsToUpdate.Select(row => row.Id);
var itemsToRemove = databaseElements.Where(row => !idsItemsToKeep.Contains(row.Id))

Последнее: удалите все элементы с идентификатором, которого больше нет в ваших элементах пользовательского интерфейса.

Примечание К настоящему времени вы запросили базу данных ровно один раз: вы выбрали все элементы для удаления. Вы не можете заказать структуру сущностей для удаления элементов без предварительной загрузки их.

dbContext.MyClasses.RemoveRange(removeList);
dbContext.MyClasses.AddRange(addList);

Для обновления в объектной структуре правильным методом будет выборка данных, а затем изменение свойств.

Некоторые люди предпочитают прикреплять элементы к трекеру изменений dbContext и сообщать, что они изменены. Однако это может быть опасно, если кто-то еще изменил некоторые свойства этих элементов, особенно если эти значения не отображаются в элементах пользовательского интерфейса. Так что делайте это только в том случае, если у вас действительно длинный список элементов для обновления.

Правильный путь:

foreach(var itemToUpdate in updateList)
{
     var fetchedItem = dbContext.MyClasses.Find(itemToUpdate.Id);
     // TODO: update changed properties of the fetchedItem with values from itemToUpdate
}

Опасный метод:

foreach(var itemToUpdate in updateList)
{
    dbContext.Entry(itemToUpdate).State = entityState.Modified;
}

Наконец:

dbContext.SaveChanges();

Улучшен метод удаления

Вы возникла проблема, когда вы заполнили элемент пользовательского интерфейса значениями базы данных, а другой процесс удалил одно из этих значений из вашей базы данных.

Когда ваш код смотрит на первичный ключ, он будет думать, что он находится в базе данных, но его больше нет. Что делать с этим элементом? Добавить еще раз? Действовать так, как если бы пользователь также хотел, чтобы он был удален?

Чтобы решить подобные проблемы, люди часто не удаляют элементы из своей базы данных, а объявляют их устаревшими. Они добавляют в таблицу логический столбец, который указывает, должен ли элемент быть удален в ближайшем будущем. Это решает проблему того, что люди хотят обновить элементы, в то время как другие хотят, чтобы они были удалены.

Регулярно, каждый месяц или около того, запускается процесс удаления всех устаревших объектов. Вероятность того, что вы захотите обновить устаревший объект, значительно ниже.

Если это необходимо для полного сохранения: не помните логическое устаревшее, но устаревшую дату. Периодически удаляйте все элементы, которые устарели в течение более длительного времени.

Хорошая вещь об устаревшем состоит в том, что, если кто-то объявил элемент устаревшим случайно, еще есть некоторое время, чтобы исправить это.

0
ответ дан Harald Coppoolse 19 January 2019 в 23:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: