Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Jakobz, Вы писали:
J>>В общем моё имхо — ни к чему было пытаться это все впихнуть в легкий и прозрачный Linq to sql. И если ты, когда припрет, напишешь sqlCommand.CommandText = "update ... set ... where ...", динозавр не прибежит и не откусит тебе голову*
VD>Это будет резко отличаться от подхода с датаконтекстом и с большой вероятностью приведет к проблемам.
Ну вот и непонятно как в подходе с датаконтекстом обрабатывать запросы типа "delete * from Blabla". Я не представляю как такое может жить вместе со всяким identity tracking.
Здравствуйте, Jakobz, Вы писали:
VD>>Это будет резко отличаться от подхода с датаконтекстом и с большой вероятностью приведет к проблемам.
J>Ну вот и непонятно как в подходе с датаконтекстом обрабатывать запросы типа "delete * from Blabla". Я не представляю как такое может жить вместе со всяким identity tracking.
Дык, мне сам этот подход и не нравится. Датоконтекст должен пойти в топку.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Jakobz, Вы писали:
VD>>>Это будет резко отличаться от подхода с датаконтекстом и с большой вероятностью приведет к проблемам.
J>>Ну вот и непонятно как в подходе с датаконтекстом обрабатывать запросы типа "delete * from Blabla". Я не представляю как такое может жить вместе со всяким identity tracking.
VD>Дык, мне сам этот подход и не нравится. Датоконтекст должен пойти в топку.
И отслеживать identity и конфликты самостоятельно? Или придумывать свой велосипед? Нет уж. Я лучше уж с DataContext, а без массовых update-ов как-нибудь проживу.
Здравствуйте, Jakobz, Вы писали:
VD>>Дык, мне сам этот подход и не нравится. Датоконтекст должен пойти в топку.
J>И отслеживать identity и конфликты самостоятельно? Или придумывать свой велосипед? Нет уж. Я лучше уж с DataContext, а без массовых update-ов как-нибудь проживу.
Не будет дурацкой схемы датаконтекстов не будет и проблем связанных с ней.
Твое identity не более чем уникальный идентификатор. Хочешь сделай счетчик на сервере, хочешь используй GUID. Это сто лет назад решенная проблема.
Конфликтов же у тебя будет даже меньше. По крайней мере ими можно будет успешно управлять.
RowID позволяет обеспечить оптимистическую блокировку. Явное управлением транзакциями и уровнем изоляции — пессимистическую. Где проблемы то?
Просто ты привык к схемам тяжелых OR-маперов. Вот и боишься, что они вдруг исчезнут.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Не будет дурацкой схемы датаконтекстов не будет и проблем связанных с ней.
Хорошая логика. Типа "нет человека — нет проблем" Не будет датаконтекстов — не будет и удобств, которые они дают.
Собственно тебя никто и не заставляет юзать DataContext. Совсем от него отказаться нельзя, но можно же select-ить в ReadOnly, а апдейтить потом как угодно.
VD>Твое identity не более чем уникальный идентификатор. Хочешь сделай счетчик на сервере, хочешь используй GUID. Это сто лет назад решенная проблема.
Я имел ввиду identity объектов:
1. select * from Persons where person_id = 1
2. юзер выбирает список персон
3. select * from Persons
Первая персона у нас теперь в виде объектов в двух экземплярах — из первого и второго запроса.
Не запутаешься с этим? Ничего что "==" для объектов нельзя будет использовать? Или будет собственный велик?
VD>Конфликтов же у тебя будет даже меньше. По крайней мере ими можно будет успешно управлять.
Откуда их станет меньше? Почему я не могу успешно управлять ими в LINQ to SQL?
VD>RowID позволяет обеспечить оптимистическую блокировку. Явное управлением транзакциями и уровнем изоляции — пессимистическую. Где проблемы то?
Проблема в том, что эта проблема в очередной раз будет решаться руками или велосипедами.
VD>Просто ты привык к схемам тяжелых OR-маперов. Вот и боишься, что они вдруг исчезнут.
Не, я вообще не привык к комфорту. На проекте, на котором я уже пару лет занят — вообще датасеты и все руками. Но у нас специфика такая, что в основном с базой только на чтение работа идет.
Здравствуйте, Jakobz, Вы писали:
J>Хорошая логика. Типа "нет человека — нет проблем" Не будет датаконтекстов — не будет и удобств, которые они дают.
А в чем удобства то?
J>Собственно тебя никто и не заставляет юзать DataContext. Совсем от него отказаться нельзя, но можно же select-ить в ReadOnly, а апдейтить потом как угодно.
Дык апдэйты не типизированными будут.
J>Я имел ввиду identity объектов: J>1. select * from Persons where person_id = 1 J>2. юзер выбирает список персон J>3. select * from Persons J>Первая персона у нас теперь в виде объектов в двух экземплярах — из первого и второго запроса.
И что? Это не проблема. Апдэйты ведь ведутся по тому самому person_id.
J>Не запутаешься с этим? Ничего что "==" для объектов нельзя будет использовать?
Это почему нельзя? Реализуй оператор корректно и используй.
J>Или будет собственный велик?
Классы все равно самому писать... точнее генерировать их функциональность. Реализация оператор сравнения делается в пол пинка. Я же не C# весь код добить собираюсь .
VD>>Конфликтов же у тебя будет даже меньше. По крайней мере ими можно будет успешно управлять.
J>Откуда их станет меньше? Почему я не могу успешно управлять ими в LINQ to SQL?
А потому что датаконтекс предлагает тебе только одну реализацию. У нее масса ограничений и проблем.
VD>>RowID позволяет обеспечить оптимистическую блокировку. Явное управлением транзакциями и уровнем изоляции — пессимистическую. Где проблемы то?
J>Проблема в том, что эта проблема в очередной раз будет решаться руками или велосипедами.
А что там решать то? В коде апдэйта автоматом докидвать RowID = RowID?
А как решать проблемы создаваемые этим самым датаконтекстом? Что если оптимистическая блокировка по логике не подходит? Подстраиваться?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Jakobz, Вы писали:
J>Здравствуйте, VladD2, Вы писали:
VD>>Не будет дурацкой схемы датаконтекстов не будет и проблем связанных с ней. J>Хорошая логика. Типа "нет человека — нет проблем" Не будет датаконтекстов — не будет и удобств, которые они дают.
Самое интересное что это работает.
J>Собственно тебя никто и не заставляет юзать DataContext. Совсем от него отказаться нельзя, но можно же select-ить в ReadOnly, а апдейтить потом как угодно.
В том то и дело что заапдейтить без работы с объектами и datacontext нельзя.
VD>>Твое identity не более чем уникальный идентификатор. Хочешь сделай счетчик на сервере, хочешь используй GUID. Это сто лет назад решенная проблема.
J>Я имел ввиду identity объектов: J>1. select * from Persons where person_id = 1 J>2. юзер выбирает список персон J>3. select * from Persons J>Первая персона у нас теперь в виде объектов в двух экземплярах — из первого и второго запроса. J>Не запутаешься с этим? Ничего что "==" для объектов нельзя будет использовать? Или будет собственный велик?
В EF есть entitykey для этих целей.
И даже без него операцию == можно определить так чтобы она нормально работала (по ключам).
VD>>Просто ты привык к схемам тяжелых OR-маперов. Вот и боишься, что они вдруг исчезнут. J>Не, я вообще не привык к комфорту. На проекте, на котором я уже пару лет занят — вообще датасеты и все руками. Но у нас специфика такая, что в основном с базой только на чтение работа идет.
На самом деле привычка больше в способе работы: считать->изменить->записать. Естественно между двумя обращениями может много чего произойти, вот и городят optimistic concurrency.
Если применить Command-query separation к работе с данными, то все операции можно будет разделить на два типа
1)выборка без побочных эффектов, identity map и unit of work не нужны, и никакой контекст не нужен.
2)операции, вызывающие изменения данных можно будет делать как отправку батча sql-команд на сервер, контекст тоже не нужен.
Здравствуйте, Jakobz, Вы писали:
J>Я имел ввиду identity объектов: J>1. select * from Persons where person_id = 1 J>2. юзер выбирает список персон J>3. select * from Persons J>Первая персона у нас теперь в виде объектов в двух экземплярах — из первого и второго запроса. J>Не запутаешься с этим? Ничего что "==" для объектов нельзя будет использовать? Или будет собственный велик?
Вот уже лет пять не испытываю с этим никаких проблем. Два экземпляра одной сущности могут мещать только в statefull архитектурах, которые являются проблемой сами по себе. А вместо "==", которое опять же в нормальном дизайне нафиг не нужно, можно с успехом использовать person1.ID == person2.ID.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, gandjustas, Вы писали:
VD>>>Не будет дурацкой схемы датаконтекстов не будет и проблем связанных с ней. J>>Хорошая логика. Типа "нет человека — нет проблем" Не будет датаконтекстов — не будет и удобств, которые они дают. G>Самое интересное что это работает.
Что работает?
J>>Собственно тебя никто и не заставляет юзать DataContext. Совсем от него отказаться нельзя, но можно же select-ить в ReadOnly, а апдейтить потом как угодно. G>В том то и дело что заапдейтить без работы с объектами и datacontext нельзя.
Ну, можно написать же самому. Нужна штука, которой нужно передать список объектов, которые нужно залить в базу, она отсортирует операции update/delete/insert по связям и в нужной очереди зальёт. Стоп... Что-то мне это напоминает...
G>В EF есть entitykey для этих целей. G>И даже без него операцию == можно определить так чтобы она нормально работала (по ключам).
Можно. Но нужно будет это делать самостоятельно.
G>На самом деле привычка больше в способе работы: считать->изменить->записать. Естественно между двумя обращениями может много чего произойти, вот и городят optimistic concurrency.
Проблема optimistic concurency вызвана ограниченостью скорости света. Ее не городят специально, это природное явление.
G>Если применить Command-query separation к работе с данными, то все операции можно будет разделить на два типа G>1)выборка без побочных эффектов, identity map и unit of work не нужны, и никакой контекст не нужен. G>2)операции, вызывающие изменения данных можно будет делать как отправку батча sql-команд на сервер, контекст тоже не нужен.
А чем это отличается от подхода "считали -> изменили -> записали"?
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Jakobz, Вы писали:
J>>Хорошая логика. Типа "нет человека — нет проблем" Не будет датаконтекстов — не будет и удобств, которые они дают.
VD>А в чем удобства то?
— identity tracking
— change tracking
J>>Собственно тебя никто и не заставляет юзать DataContext. Совсем от него отказаться нельзя, но можно же select-ить в ReadOnly, а апдейтить потом как угодно.
VD>Дык апдэйты не типизированными будут.
Апдейть через другой DataContext. Или пиши своё — со множественными апдейтами.
J>>Я имел ввиду identity объектов: J>>1. select * from Persons where person_id = 1 J>>2. юзер выбирает список персон J>>3. select * from Persons J>>Первая персона у нас теперь в виде объектов в двух экземплярах — из первого и второго запроса.
VD>И что? Это не проблема. Апдэйты ведь ведутся по тому самому person_id.
Какую из персон менять будешь? Не перепутаешь потом какую в базу потом запихивать? Не получится что обе-две в случайном порядке?
VD>>>Конфликтов же у тебя будет даже меньше. По крайней мере ими можно будет успешно управлять.
J>>Откуда их станет меньше? Почему я не могу успешно управлять ими в LINQ to SQL?
VD>А потому что датаконтекс предлагает тебе только одну реализацию. У нее масса ограничений и проблем.
Датаконтект предлагает реализацию оптимистических блокировок. И не мешает делать пессимистические. Разве кроме этих двух есть какие-то другие подходы?
VD>А что там решать то? В коде апдэйта автоматом докидвать RowID = RowID?
Да. Еще обрабатывать ошибки и заворачивать их в удобоваримый формат — что случилось, наша версия строки, версия из базы и т.п.
VD>А как решать проблемы создаваемые этим самым датаконтекстом? Что если оптимистическая блокировка по логике не подходит? Подстраиваться?
Отключать оптимистический контроль. Включать блокировку при запросе, если все проводится в одну транзакцию. Если не в одну транзакцию — наверное делать какой-то lock manager. Не вижу чтобы Linq to SQL здесь навязывала именно свое решение.
Здравствуйте, IT, Вы писали:
J>>Я имел ввиду identity объектов: J>>1. select * from Persons where person_id = 1 J>>2. юзер выбирает список персон J>>3. select * from Persons J>>Первая персона у нас теперь в виде объектов в двух экземплярах — из первого и второго запроса. J>>Не запутаешься с этим? Ничего что "==" для объектов нельзя будет использовать? Или будет собственный велик?
IT>Вот уже лет пять не испытываю с этим никаких проблем. Два экземпляра одной сущности могут мещать только в statefull архитектурах, которые являются проблемой сами по себе. А вместо "==", которое опять же в нормальном дизайне нафиг не нужно, можно с успехом использовать person1.ID == person2.ID.
А что ты понимаешь под базвордом "statefull-архитектура"? Почему дизайн с person1 == person2 — не нормален?
J>>>Собственно тебя никто и не заставляет юзать DataContext. Совсем от него отказаться нельзя, но можно же select-ить в ReadOnly, а апдейтить потом как угодно. G>>В том то и дело что заапдейтить без работы с объектами и datacontext нельзя. J>Ну, можно написать же самому. Нужна штука, которой нужно передать список объектов, которые нужно залить в базу, она отсортирует операции update/delete/insert по связям и в нужной очереди зальёт. Стоп... Что-то мне это напоминает...
Неверно. Не надо никуда передавать объекты.
G>>В EF есть entitykey для этих целей. G>>И даже без него операцию == можно определить так чтобы она нормально работала (по ключам). J>Можно. Но нужно будет это делать самостоятельно.
Можно и не сравнивать сущности, а сравнивать их ключевые поля.
Переопределять равенство имеет смысл в случае составных ключей в POCO-сущностях.
G>>На самом деле привычка больше в способе работы: считать->изменить->записать. Естественно между двумя обращениями может много чего произойти, вот и городят optimistic concurrency. J>Проблема optimistic concurency вызвана ограниченостью скорости света. Ее не городят специально, это природное явление.
На самом деле городят, потому что сама БД обеспечивает pessimistic concurrency.
G>>Если применить Command-query separation к работе с данными, то все операции можно будет разделить на два типа G>>1)выборка без побочных эффектов, identity map и unit of work не нужны, и никакой контекст не нужен. G>>2)операции, вызывающие изменения данных можно будет делать как отправку батча sql-команд на сервер, контекст тоже не нужен.
J>А чем это отличается от подхода "считали -> изменили -> записали"?
Все операции изменения данных выполняются в СУБД с блокировками.
Здравствуйте, gandjustas, Вы писали:
J>>>>Собственно тебя никто и не заставляет юзать DataContext. Совсем от него отказаться нельзя, но можно же select-ить в ReadOnly, а апдейтить потом как угодно. G>>>В том то и дело что заапдейтить без работы с объектами и datacontext нельзя. J>>Ну, можно написать же самому. Нужна штука, которой нужно передать список объектов, которые нужно залить в базу, она отсортирует операции update/delete/insert по связям и в нужной очереди зальёт. Стоп... Что-то мне это напоминает... G>Неверно. Не надо никуда передавать объекты.
Ок. Если нужно залить несколько разных объектов кто будет заниматься сортировкой операций insert/update/delete?
G>>>В EF есть entitykey для этих целей. G>>>И даже без него операцию == можно определить так чтобы она нормально работала (по ключам). J>>Можно. Но нужно будет это делать самостоятельно. G>Можно и не сравнивать сущности, а сравнивать их ключевые поля. G>Переопределять равенство имеет смысл в случае составных ключей в POCO-сущностях.
Я в другой ветке писал про это. Что если у нас два одинаковых объекты и мы поменяем только один?
G>>>На самом деле привычка больше в способе работы: считать->изменить->записать. Естественно между двумя обращениями может много чего произойти, вот и городят optimistic concurrency. J>>Проблема optimistic concurency вызвана ограниченостью скорости света. Ее не городят специально, это природное явление. G>На самом деле городят, потому что сама БД обеспечивает pessimistic concurrency.
Pessimistic — да, обеспечивает. На уровне одного соединения/транзакции. Как средствами СУБД обрабатывать классическую ситуацию: чувак открыл форму редактирования, ушел домой, а кому-то нужно что-то в ней этой же форме поправить?
G>>>Если применить Command-query separation к работе с данными, то все операции можно будет разделить на два типа G>>>1)выборка без побочных эффектов, identity map и unit of work не нужны, и никакой контекст не нужен. G>>>2)операции, вызывающие изменения данных можно будет делать как отправку батча sql-команд на сервер, контекст тоже не нужен.
J>>А чем это отличается от подхода "считали -> изменили -> записали"? G>Все операции изменения данных выполняются в СУБД с блокировками.
Update() в LINQ тоже с блокировками выполняется и в одной транзакции. Странно, зачем там optimistic concurency?
Здравствуйте, Jakobz, Вы писали:
J>Здравствуйте, gandjustas, Вы писали:
J>>>>>Собственно тебя никто и не заставляет юзать DataContext. Совсем от него отказаться нельзя, но можно же select-ить в ReadOnly, а апдейтить потом как угодно. G>>>>В том то и дело что заапдейтить без работы с объектами и datacontext нельзя. J>>>Ну, можно написать же самому. Нужна штука, которой нужно передать список объектов, которые нужно залить в базу, она отсортирует операции update/delete/insert по связям и в нужной очереди зальёт. Стоп... Что-то мне это напоминает... G>>Неверно. Не надо никуда передавать объекты.
J>Ок. Если нужно залить несколько разных объектов кто будет заниматься сортировкой операций insert/update/delete?
В каком порядке передали, в таком и выполнять.
G>>>>В EF есть entitykey для этих целей. G>>>>И даже без него операцию == можно определить так чтобы она нормально работала (по ключам). J>>>Можно. Но нужно будет это делать самостоятельно. G>>Можно и не сравнивать сущности, а сравнивать их ключевые поля. G>>Переопределять равенство имеет смысл в случае составных ключей в POCO-сущностях. J>Я в другой ветке писал про это. Что если у нас два одинаковых объекты и мы поменяем только один?
Тот который укажем.
G>>>>На самом деле привычка больше в способе работы: считать->изменить->записать. Естественно между двумя обращениями может много чего произойти, вот и городят optimistic concurrency. J>>>Проблема optimistic concurency вызвана ограниченостью скорости света. Ее не городят специально, это природное явление. G>>На самом деле городят, потому что сама БД обеспечивает pessimistic concurrency. J>Pessimistic — да, обеспечивает. На уровне одного соединения/транзакции. Как средствами СУБД обрабатывать классическую ситуацию: чувак открыл форму редактирования, ушел домой, а кому-то нужно что-то в ней этой же форме поправить?
Треназакцию держать не надо. Встроенные возможности контекства тоже не попогут (веб-приложение например).
Не факт что вообще concurrency тут неоходимо, вполне возможно last wins и все.
G>>>>Если применить Command-query separation к работе с данными, то все операции можно будет разделить на два типа G>>>>1)выборка без побочных эффектов, identity map и unit of work не нужны, и никакой контекст не нужен. G>>>>2)операции, вызывающие изменения данных можно будет делать как отправку батча sql-команд на сервер, контекст тоже не нужен.
J>>>А чем это отличается от подхода "считали -> изменили -> записали"? G>>Все операции изменения данных выполняются в СУБД с блокировками.
J>Update() в LINQ тоже с блокировками выполняется и в одной транзакции. Странно, зачем там optimistic concurency?
Update() выполняется, а чтение+Update — нет, для этого и городится.
При этом во многих случаях где optimistic concurency действительно нужно возможностей контекста не хватает.
Здравствуйте, gandjustas, Вы писали:
J>>Ок. Если нужно залить несколько разных объектов кто будет заниматься сортировкой операций insert/update/delete? G>В каком порядке передали, в таком и выполнять.
Сортировать нужно в любом случае. Вопрос только кто будет этим заниматься.
Ну или можно constraint-ы в базе отключить.
G>>>>>В EF есть entitykey для этих целей. G>>>>>И даже без него операцию == можно определить так чтобы она нормально работала (по ключам). J>>>>Можно. Но нужно будет это делать самостоятельно. G>>>Можно и не сравнивать сущности, а сравнивать их ключевые поля. G>>>Переопределять равенство имеет смысл в случае составных ключей в POCO-сущностях. J>>Я в другой ветке писал про это. Что если у нас два одинаковых объекты и мы поменяем только один? G>Тот который укажем.
Ну ок, можно и так. Но мне кажется что приятно быть увереным что внутри контекста может быть только один объект для одного ID. А ну как не тот укажешь или что еще страшное случится?
G>>>>>На самом деле привычка больше в способе работы: считать->изменить->записать. Естественно между двумя обращениями может много чего произойти, вот и городят optimistic concurrency. J>>>>Проблема optimistic concurency вызвана ограниченостью скорости света. Ее не городят специально, это природное явление. G>>>На самом деле городят, потому что сама БД обеспечивает pessimistic concurrency. J>>Pessimistic — да, обеспечивает. На уровне одного соединения/транзакции. Как средствами СУБД обрабатывать классическую ситуацию: чувак открыл форму редактирования, ушел домой, а кому-то нужно что-то в ней этой же форме поправить? G>Треназакцию держать не надо. Встроенные возможности контекства тоже не попогут (веб-приложение например).
Почему встроеные возможности контекста не помогут? Вполне себе оно на вебе работает. Только нужно RowVersion в скрытое поле положить или как-то иначе сохранить, но это уже извините.
G>Не факт что вообще concurrency тут неоходимо, вполне возможно last wins и все.
Давай все-таки рассматривать ситуацию когда "last wins" недостаточно.
J>>Update() в LINQ тоже с блокировками выполняется и в одной транзакции. Странно, зачем там optimistic concurency? G>Update() выполняется, а чтение+Update — нет, для этого и городится.
Выполняй чтение в одной транзакции с SubmitChanges(), в чем проблема?
G>При этом во многих случаях где optimistic concurency действительно нужно возможностей контекста не хватает.
Здравствуйте, Jakobz, Вы писали:
G>>>>>>В EF есть entitykey для этих целей. G>>>>>>И даже без него операцию == можно определить так чтобы она нормально работала (по ключам). J>>>>>Можно. Но нужно будет это делать самостоятельно. G>>>>Можно и не сравнивать сущности, а сравнивать их ключевые поля. G>>>>Переопределять равенство имеет смысл в случае составных ключей в POCO-сущностях. J>>>Я в другой ветке писал про это. Что если у нас два одинаковых объекты и мы поменяем только один? G>>Тот который укажем.
J>Ну ок, можно и так. Но мне кажется что приятно быть увереным что внутри контекста может быть только один объект для одного ID. А ну как не тот укажешь или что еще страшное случится?
Вообще говоря получение одной сущности двумя путями — признак хренового проектирования.
G>>>>>>На самом деле привычка больше в способе работы: считать->изменить->записать. Естественно между двумя обращениями может много чего произойти, вот и городят optimistic concurrency. J>>>>>Проблема optimistic concurency вызвана ограниченостью скорости света. Ее не городят специально, это природное явление. G>>>>На самом деле городят, потому что сама БД обеспечивает pessimistic concurrency. J>>>Pessimistic — да, обеспечивает. На уровне одного соединения/транзакции. Как средствами СУБД обрабатывать классическую ситуацию: чувак открыл форму редактирования, ушел домой, а кому-то нужно что-то в ней этой же форме поправить? G>>Треназакцию держать не надо. Встроенные возможности контекства тоже не попогут (веб-приложение например).
J>Почему встроеные возможности контекста не помогут? Вполне себе оно на вебе работает. Только нужно RowVersion в скрытое поле положить или как-то иначе сохранить, но это уже извините.
И этот же rowversion надо получать на клиентской стороне в момент окончания длительной операции.
Что ОРМы предлагают для этого? Только запрос писать? Так это я и без контекста могу.
G>>Не факт что вообще concurrency тут неоходимо, вполне возможно last wins и все. J>Давай все-таки рассматривать ситуацию когда "last wins" недостаточно.
Давайте.
J>>>Update() в LINQ тоже с блокировками выполняется и в одной транзакции. Странно, зачем там optimistic concurency? G>>Update() выполняется, а чтение+Update — нет, для этого и городится. J>Выполняй чтение в одной транзакции с SubmitChanges(), в чем проблема?
Проблема в двух round-trip, когда достаточно одного.
G>>При этом во многих случаях где optimistic concurency действительно нужно возможностей контекста не хватает. J>Каких, например?
Если правильность операции зависит не только от изменяемого объекта. Где-то в этой ветке уже приводили пример.
Здравствуйте, Jakobz, Вы писали:
J>Я в другой ветке писал про это. Что если у нас два одинаковых объекты и мы поменяем только один?
У тебя какие-то невероятные проблемы с пониманием не используемых тобой техник.
Попробуй вдумчиво прочесть мои слова. ОК?
При использовании update/insert/delete объекты вообще не меняются. Они просто ипользуются для временного хранения данных считанных из БД.
При этом никого не трогает вопрос синхронизации объектов. Актуальные данные есть только в БД и только после фиксации транзакции.
Короче — это подход при котором объекты ничто данные все.
Понятно?
При этом нет никаких идетити, хренньтити и т.п. Есть только данные и их разработка.
Это аналогично обработки данных хранимых в файле. Ты считываешь данные из файла, превращаешь (временно) в объекты, преобразуешь данные и записываешь их обратно. Да, ты можешь считать данные два раза и изменить только одну копию. Но это твои проблемы. Твоя стратегия.
J>Pessimistic — да, обеспечивает. На уровне одного соединения/транзакции. Как средствами СУБД обрабатывать классическую ситуацию: чувак открыл форму редактирования, ушел домой, а кому-то нужно что-то в ней этой же форме поправить?
Это зависит от стратегии программы.
1. Программа может просто перезаписать изменения.
2. Программа может при обновлении записей использовать в качестве ключа RowID (изменяемый в случае изменения записи) или просто все значимые данные строки. Тогда в случае если строка была изменена во время редактирования БД выдаст сообщение об ошибке (такая строка не существует).
Ты что с БД без OR-маперов вообще не работал никогда?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Jakobz, Вы писали:
G>>Тот который укажем.
J>Ну ок, можно и так. Но мне кажется что приятно быть увереным что внутри контекста может быть только один объект для одного ID. А ну как не тот укажешь или что еще страшное случится?
Не. Приятно когда контекста нет вообще и о нем не болит голова. Хотим — запишем данные в БД, хотим пошлем их на фиг. Хотим — изменим сразу много записей в БД.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Jakobz, Вы писали:
VD>>А в чем удобства то?
J>- identity tracking J>- change tracking
Сами ради себя что ли?
Или это все ради удовольствия возиться с обработкой объектов в циклах?
Пойми все эти красивые слова "identity", "tracking", "change tracking" придуманы только ради того, чтобы программист думал что он работает не с данными взятыми из БД, а с объектой моделью которая сама собой (чудесным образом) сохраняет свое состояние.
Вот только ООП супротив придуманной 50 лет назад СУБД — это козьи потягушки. Запросы намного мощнее и безопаснее императивного кода.
Забудь про весь этот трекинг и жить станет проще и лучше.
J>Апдейть через другой DataContext. Или пиши своё — со множественными апдейтами.
В задницу твой DataContext.
VD>>И что? Это не проблема. Апдэйты ведь ведутся по тому самому person_id.
J>Какую из персон менять будешь? Не перепутаешь потом какую в базу потом запихивать? Не получится что обе-две в случайном порядке?
Да я не буду менять персон. Я поле поменяю. Причем то что изменил пользователь. Я тут ну никак не ошибусь.
J>Датаконтект предлагает реализацию оптимистических блокировок. И не мешает делать пессимистические. Разве кроме этих двух есть какие-то другие подходы?
В задницу твой датаконтект и то что он предлагает. Я без него могу намного эффективнее работать.
Записать данные одного измененного объекта не проблема. Группы — тоже. Код для этого пишется на коленке за 3 часа. Выполнить его в рамках одной транзакции — тоже элементарно. А вот когда тебе придется делать сложные массовые обновления данных (ну, там сумму по заказу в поле поместить или еще что), то сделать это запросом в сто раз проще будет.
VD>>А что там решать то? В коде апдэйта автоматом докидвать RowID = RowID? J>Да. Еще обрабатывать ошибки и заворачивать их в удобоваримый формат — что случилось, наша версия строки, версия из базы и т.п.
А как без обработки то? Если данные изменились, то опять же нужна стратегия — что делать. Может быть забыть изменения и перечитать данные. Может быть в форме отобразить и измененные данные, и введенные пользователем и если тот захочет, то выберет те что ему нужны. А может быть будет еще какая-то стратегия. И я хочу сам ее определять, а не зависеть от датаконтекта реализованного индусами.
VD>>А как решать проблемы создаваемые этим самым датаконтекстом? Что если оптимистическая блокировка по логике не подходит? Подстраиваться?
J>Отключать оптимистический контроль. Включать блокировку при запросе, если все проводится в одну транзакцию. Если не в одну транзакцию — наверное делать какой-то lock manager. Не вижу чтобы Linq to SQL здесь навязывала именно свое решение.
И держать блокировку все время работы клиента? Здорово! А нам все что было нужно — это сумировать данные по заказу и запихнуть их в поле "СуммаЗаказа". Глупо, не правда ли?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Jakobz, Вы писали:
J>А что ты понимаешь под базвордом "statefull-архитектура"?
Архитектуры построенные на хранении состояния.
J>Почему дизайн с person1 == person2 — не нормален?
Потому что в stateless системе я представить не могу где это может понадобиться. А если понадобится, то написать person1.ID == person2.ID я не переломлюсь. Так даже понятней будет.
Если нам не помогут, то мы тоже никого не пощадим.