2009-03-26 2 views
3

В последнее время я читал в LINQ, чтобы начать его реализацию, и есть определенная вещь о том, как он генерирует запросы UPDATE, которые меня беспокоят.Обнаружение конфликтов LINQ: настройка атрибута UpdateCheck

Создание кода Entities автоматически с помощью SQLMetal или Object Relational Designer, по-видимому, все поля для всех таблиц будет получить атрибут UpdateCheck.Always, что означает, что для каждого UPDATE и DELETE запроса, я получу SQL заявление, как это :

UPDATE table SET a = 'a' WHERE a='x' AND b='x' ... AND z='x', ad infinitum 

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

Конечно, в некоторых очень чувствительных приложений что-то подобное может быть полезно, но для типичного веб-приложения (думаю, переполнение стека), похоже, UpdateCheck.WhenChanged будет более подходящим по умолчанию, и я бы лично предпочитают UpdateCheck.Never, так как LINQ будет обновлять только измененные поля, а не все поля, и в большинстве реальных случаев второй человек, редактирующий что-то, побеждает в любом случае.

Это означает, что если двум людям удастся отредактировать одно и то же поле той же строки за небольшое время между чтением этой строки и включением UPDATE, тогда конфликт, который будет найден, не будет запущен. Но на самом деле это очень редкий случай. Единственное, на что мы можем обратить внимание, когда два человека меняют одно и то же, не будут пойманы этим, потому что они не будут нажимать «Отправить» в одно и то же время в любом случае, поэтому конфликт во время второго DataContext не будет считывает и обновляет запись (если только DataContext не остается открытым и не сохраняется в сеансе при показе страницы или какой-либо другой плохой идее).

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

Итак, мой первый вопрос: я ошибаюсь, полагая это? (опять же, для «типичных» веб-приложений, а не для банковских приложений) У меня отсутствует какая-то причина, почему UpdateCheck.Always по умолчанию - разумная идея?

Мой второй вопрос: могу ли я изменить это цивилизованно? Есть ли способ указать SQLMetal или ORD, для которых установлен атрибут UpdateCheck?
Я пытаюсь избежать ситуации, когда я должен помнить, чтобы запустить инструмент, я должен будет сделать это, чтобы взять некоторые регулярные выражения и отредактировать все атрибуты в файле напрямую, потому что очевидно, что в какой- Запустите SQLMetal после обновления базы данных, мы не запустим этот инструмент, и весь наш код будет разбит очень тонкими способами, которые мы, вероятно, не найдем во время тестирования в dev.

Любые предложения?
Истории о войне более чем приветствуются, мне бы хотелось узнать из опыта других людей об этом.

спасибо!

ответ

2

Ну, чтобы ответить на первый вопрос - я согласен с вами. Я не большой поклонник этого «встроенного» оптимистического параллелизма, особенно если у вас есть столбцы timestamp или любые поля, которые не гарантируются одинаково после обновления.

Чтобы решить второй вопрос - я не знаю, как переопределить подход по умолчанию SqlMetal (UpdateCheck = Always), мы закончили тем, что написали инструмент, который устанавливает UpdateCheck = Never для соответствующих столбцов. Мы используем пакетный файл для вызова SqlMetal и последующего запуска инструмента).

О, хотя я думаю об этом - было также полезно найти, что SqlMetal также моделирует отношения, чтобы установить внешний ключ в значение null вместо «Delete On Null» (в частности, для соединения таблиц). Мы должны были использовать один и тот же инструмент пост-генерации, чтобы соответствующим образом установить их.

+0

Я сделал то же самое! – Keltex

Смежные вопросы