Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > LINQ (Language-Integrated Query) > DeleteAllOnSubmit и триггер


Автор: Magnetic 23.6.2008, 15:51
Есть примерно такой код:
Код

this.db.DeleteAllOnSubmit(itemsList);
this.db.SubmitChanges();

LINQ на базе пытается выполнить запрос на удаление записей, причем для каждой сущности выполняется свой запрос, в котором в предложении where поиск идет по всем колонкам таблицы. Приблизительный смысл запросов от LINQ при вызове метода SubmitChanges следующий:
Код

delete from category where id=1, name='name', lft='lft', rght='rhgt'

И таких запросов несколько.
Проблема вот в чем. Есть триггер на удаление. Он срабатывает после первого запроса на удаление, меняет lft, rght значения, из-за чего последующие запросы удаления не могут найти соответвующих записей. В результате метод SubmitChanges выбрасывает исключение со словом Conflict в названии и ни одна запись не удаляется. 
Можно ли LINQ указать, чтобы он удалял записи только по ID, а не по всем полям? Например, чтобы LINQ выполнял на базе запросы такого вида:
Код

delete from category where id=1

вместо указанного выше.

Автор: Idsa 23.6.2008, 18:55
Magnetic, в ORM вообще туго с batch update и delete командами. Для LINQ есть http://www.aneyfamily.com/terryandann/post/2008/04/Batch-Updates-and-Deletes-with-LINQ-to-SQL.aspx. В конце статьи исходный код с методами расширения.

Автор: akizelokro 24.6.2008, 12:30
Цитата

You can use the stored procedure instead of the normal auto-generated update command by defining a method on your strongly-typed DataContext. Even if the DataContext class is being auto-generated by the DLinq code generation tool, you can still specify these methods in a partial class of your own. 
Код

public partial class Northwind : DataContext
{
    ...
    [UpdateMethod]
    public void OnProductUpdate(Product original, Product current) {
  // Execute the stored procedure for UnitsInStock update
  if (original.UnitsInStock != current.UnitsInStock) {
    int rowCount = this.ExecuteCommand(
    "exec UpdateProductStock " +
    "@id={0}, @originalUnits={1}, @decrement={2}",
    original.ProductID,
    original.UnitsInStock,
    (original.UnitsInStock - current.UnitsInStock)
    );
    if (rowCount < 1)
    throw new OptimisticConcurrencyException();
  }
  ...
    }
}




Аналогично, я предполагаю, для удаления.
Надо завершать перевод с введением в DLinq. Но у меня с временем напряг (я тут озадачился с переездом в другой город), поэтому и торможу

Автор: Idsa 24.6.2008, 16:08
akizelokro, Вы уверены, что Ваш метод решает проблему? Что-то мне подсказывает, что он сгенерирует примерно тот запрос, который не устраивает Magnetic:
Цитата(Magnetic @  23.6.2008,  19:51 Найти цитируемый пост)
delete from category where id=1, name='name', lft='lft', rght='rhgt'

(только с update).

Автор: Magnetic 24.6.2008, 16:33
Поиски в интернете привели к следующему результату. Можно наследоваться от DataContext, переписать SubmitChanges и в нем вызвать ExecuteCommand c запросом, сформированным вручную, извлекая id из всех сущностей идущих на удаление. Жаль, что в LINQ нет возможности указать, чтобы он формировал запросы на удаление и обновление с поиском только по праймари кей, ведь если есть праймари кей, то чаще всего при обновлении и удалении записей через ооп поиск по всем полям и не требуется. Придется делать лишнюю работу. Может есть решение проще?

Автор: Idsa 24.6.2008, 16:48
Цитата(Magnetic @  24.6.2008,  20:33 Найти цитируемый пост)
Может есть решение проще?

Вы ходили по ссылке, которую я указал выше?

Автор: PashaPash 24.6.2008, 17:13
Самописные хранимые процедуры и поддержка batch операций это конечно круто. Но проблема легко решается мышой в дизайнере - сменой аттирибута UpdateCheck для лишних колонок с Always на Never или WhenChanged. Или, как вариант, введением поля с IsVersion=true.

Автор: Magnetic 24.6.2008, 17:35
Idsa, посчитал, что реализовать решение, которо я нашел и рассказал в предыдущем посте будет проще реализовать, чем разобраться в предложенной статье, тем более на английском, но все равно спасибо за ответ.

PashaPash, то что нужно. Спасибо большое!

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)