![]() |
Модераторы: gambit |
![]() ![]() ![]() |
|
Red Wind |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 280 Регистрация: 25.6.2004 Где: Минск Репутация: нет Всего: 2 |
Доброго времени суток!
Начал изучать LINQ to SQL. И сразу же наткнулся на неприятную особенность. После удаления каждого объекта например northwind.Orders.DeleteAllOnSubmit(customer.Orders) нужно вызывать метод northwind.SubmitChanges() То есть если я сначала вызову northwind.Orders.DeleteAllOnSubmit(customer.Orders) потом northwind.Customers.DeleteOnSubmit(customer) а уже после этого northwind.SubmitChanges() то падает ошибка:
Вот код который работает. Но мне не нравиться то что нужно два раза вызывать метод northwind.SubmitChanges(); Как этого избежать?
|
||||
|
|||||
Idsa |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2086 Регистрация: 5.12.2006 Где: Томск Репутация: 5 Всего: 62 |
Посмотрите, какое Delete-правило выставлено для FK из Customers.CustomerId в Orders.CustomerId.
Это сообщение отредактировал(а) Idsa - 25.3.2009, 19:56 |
|||
|
||||
Red Wind |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 280 Регистрация: 25.6.2004 Где: Минск Репутация: нет Всего: 2 |
Delete rule: No Action.
|
|||
|
||||
Idsa |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2086 Регистрация: 5.12.2006 Где: Томск Репутация: 5 Всего: 62 |
Red Wind, приведите код из профайлера при неработающем подходе. Такое ощущение, что Linq To Sql сначала отдает команду на удаление заказчика (и тут, естественно, возникает конфликт), а потом уже команду удаления заказов (хотя до этого не доходит).
|
|||
|
||||
Red Wind |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 280 Регистрация: 25.6.2004 Где: Минск Репутация: нет Всего: 2 |
Это понятно. Но дело в том, что это пример из книги, на бд которая шла вместе с книгой. И там всё работало с одним вызовом SubmitChanges. То есть я подумал, что linq to sql должен сам разруливать такие вещи.
Профайлера на этой машине у меня нет. Вот последнее сообщение которое выдаёт DataContext.Log:
Так что да, сначала удаляется Customers. |
|||
|
||||
Idsa |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2086 Регистрация: 5.12.2006 Где: Томск Репутация: 5 Всего: 62 |
Хех... Это какой-то идиотизм. LINQ To SQL, конечно, не отличается особой смышленностью... но уж порядок Delete'ов-то должен соблюдаться.
P. S. Задумался, а не глюканет ли на этом примере EF... |
|||
|
||||
PashaPash |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1233 Регистрация: 3.1.2008 Репутация: 4 Всего: 49 |
Red Wind, поставь каскадное удаление и удаляй только кастомера
|
|||
|
||||
Idsa |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2086 Регистрация: 5.12.2006 Где: Томск Репутация: 5 Всего: 62 |
PashaPash, это да... но ведь, согласись, ORM должна соблюдать порядок выполнения операций.
|
|||
|
||||
PashaPash |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1233 Регистрация: 3.1.2008 Репутация: 4 Всего: 49 |
Idsa, наоборот, не должна - вряд ли ORM может правильно разрешить циклические зависимости.
Вот в примере выше - как можно проверять целостность на уровне базы, а требовать соблюдения этой целостности от ORM? |
|||
|
||||
Idsa |
|
||||||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2086 Регистрация: 5.12.2006 Где: Томск Репутация: 5 Всего: 62 |
Вот кусочек из реальной EF-модели:
Ключевая строчка - <OnDelete Action="Cascade" /> Но это, насколько я понимаю, всего лишь дает команду удалить дочерние сущности из кэша: запрос на удаление дочерних записей не генерируется (и правильно: эта логика должна быть реализована в самой БД, благо средств для этого предостаточно).
Так я не требую от ORM соблюдения целостности. Я всего-то требую, чтобы она выполняла команды в том порядке, в котором я их задаю. Это сообщение отредактировал(а) Idsa - 25.3.2009, 23:10 |
||||||
|
|||||||
Red Wind |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 280 Регистрация: 25.6.2004 Где: Минск Репутация: нет Всего: 2 |
Не в этом дело. Сейчас я хочу разобратсья как работает LINQ to SQL. Взял скопипастил код примера из книжки, в котором по большому счёту делается то же самое что и у меня. Этот пример работает. Но принципиальной разницы я не вижу. Так в чём может быть дело?
Это сообщение отредактировал(а) Red Wind - 26.3.2009, 12:43 |
|||
|
||||
PashaPash |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1233 Регистрация: 3.1.2008 Репутация: 4 Всего: 49 |
EF это не только ORM, это способ получить некую абстрактную модель, которая спрячет за собой все детали работы с базой данных. Т.е. пользоваель EF не знает что там внутри есть база. А пользователь ORM - знает, и должен учитывать ее поведение.
Так и происходит, только DeleteOnSubmit и DeleteAllOnSubmit - разные команды. Если явно удалять Order-ы по одному - они удалятся раньше. |
|||
|
||||
Red Wind |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 280 Регистрация: 25.6.2004 Где: Минск Репутация: нет Всего: 2 |
Интересно. Сейчас попробую. Но почему так происходит? На мой взягляд, принципиальной разницы между DeleteOnSubmit и DeleteAllOnSubmit нет. Тем более в моём случае, DeleteAllOnSubmit удаляет одну запись. Добавлено через 13 минут и 55 секунд Не помогло. И заметил такую фишку, что после вызова northwind.Orders.DeleteOnSubmit(customer.Orders.First()) количество Orders у customer не меняется. Разве это правильно? |
|||
|
||||
PashaPash |
|
||||||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1233 Регистрация: 3.1.2008 Репутация: 4 Всего: 49 |
Присмотрись внимательнее - оно помогло, просто надо удалять еще и Order_Detail. И, кстати, оказалось что Linq To Sql порядок нормально обнаруживает, и DeleteAllOnSubmit и DeleteOnSubmit работают одновременно. Вот тебе 4 примера рабочего кода:
|
||||||||
|
|||||||||
Red Wind |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 280 Регистрация: 25.6.2004 Где: Минск Репутация: нет Всего: 2 |
Попробовал завести эти примеры. У меня они не работают. Падает точно такая же ошибка как и раньше. Кстати в чём фишка удаления Order_Details? Для Order'а который я удаляю нет Order_Details.
|
|||
|
||||
![]() ![]() ![]() |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | LINQ (Language-Integrated Query) | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |