Удаление нескольких записей в ESQ

Добрый день!

Коллеги, подскажите, пожалуйста, какой наиболее корректный способ массово (в цикле) удалять записи в БД с помощью ESQ?

Вариант с foreach:

EntitySchema schemaDeleteEntity =userConnection.EntitySchemaManager.GetInstanceByName(EntityName);
EntitySchemaQuery esqDeleteEntity = new EntitySchemaQuery(schemaDeleteEntity);
esqDeleteEntity.AddAllSchemaColumns();
esqDeleteEntity.Filters.Add(esqDeleteEntity.CreateFilterWithParameters(FilterComparisonType.Equal, AccountIdField, AccountId));
EntityCollection entitiesDeleteEntity = esqDeleteEntity.GetEntityCollection(userConnection);
  foreach (Entity deleteentity in  entitiesDeleteEntity)
  {
      deleteentity.Delete();
  }

возвращает exception "Коллекция была изменена после создания экземпляра перечислителя."

Если заменить на простой for:

for(int i = entitiesDeleteEntity.Count-1;i>=0;i--)
{
        entitiesDeleteEntity[i].Delete();
}

Код отрабатывает корректно, но при нагрузке удаление периодически вызывает exception о незавршённых транзакциях вида:
Данный SqlTransaction завершен; его повторное использование невозможно.   в System.Data.SqlClient.SqlTransaction.ZombieCheck()
   в System.Data.SqlClient.SqlTransaction.Rollback()
   в Terrasoft.Core.DB.DBExecutor.RollbackTransaction()
   в Terrasoft.Core.Entities.Entity.ExecuteDelete(Delete delete, Object keyValue)
   в Terrasoft.Core.Entities.Entity.Delete(Object keyValue)
   в Terrasoft.Core.Entities.Entity.Delete()

Как всё-таки правильнее?

Спасибо!

Нравится

1 комментарий

Добрый день!
Для массового удаления лучше не использовать EntitySchemaQuery, так как ESQ накладывает права на запрос. Лучше всего использовать либо класс Delete, или же использовать хранимую процедуру.
Единственный случай, когда нужно использовать ESQ - это если вам нужно запускать процессы, которые настроенны на сигнал "удаления записи", но и в этом случае лучше найти альтернативу по запуску доп логики после удаления

Показать все комментарии