Re[9]: Некоторые мысли о LINQ
От: Tissot Россия  
Дата: 05.01.09 21:24
Оценка:
Здравствуйте, gandjustas, Вы писали:

T>>Я видимо не до конца понимаю, что имеется в виду.

T>>Наследование, интерфейсы, методы, атрибуты — для меня это удобства, от которых я бы очень не хотел отказываться.
G>Не отказывайтесь. Но базовая модель для данных — ER (потому что БД так работает) и объектная модель должна при желании надстраиваться над ER, причем все "прелести" как ленивая загрузка должны быть опциональны и по-умолчанию выключены.

Может поподробней описать, что имеется в виду? В реляционной модели не поддерживаются такие понятия, как наследование, область видимости для данных, методы, меняющие состояние entity. Если все это привнести в нее, то это будет не реляционная, а вполне себе объектная модель.

T>>>>Как EF, так и Linq2Sql поддерживают ленивую загрузку.

G>>>Неправда, EF не поддерживает ленивую зугрузку. Да и вообще ленивая загрузка — большое зло, в программе надо видеть где происходит обращение к БД.
T>>Согласен, погорячился, но Linq2Sql поддержиает
G>В Linq2SQL гораздо сложнее отключить ленивую загрузкую.

Убираешь все relation-ы и ленивые поля и получаешь то, к чему ты так стремишься.

T>>Не забывай добавлять "в простых (а потому нежизненных) сценарих". Все равно нужно будет делать валидацию/проверку прав/аудит, тут-то объект у вас в память и заползет.

G>Да ну? Как раз security можно создать дополнительными фильтрами выборки. В моих проектах так и делается, при выборке в память не тянутся объекты для которых доступа нету.
G>При записи все равно приходится вытягивать нужный объект(с теми же secutiry фильтрами). При наличии операторов update\delete теже фильтры перекочевали бы в соответствующие запросы и не было бы необходимости тянуть целый объект.

Тогда бы написание этих запросов превратилось в сущий ад. В лес такое счастье.

T>>>>Де-факто, прежде чем изменить что-то в базе понадобится еще сделать валидацию, поправить информацию о дате последнего изменения, изменить зависимые данные и так далее и тому подобное.

G>>>То что касается целостности данных должно находится в БД и все проверки и изменения должны осуществляться самой БД.
T>>Ну приплыли.
G>Ну не знаю как у вас, а у меня так работает. И отлично работает, по поводу lastModified вообще никто не парится.

Аудит — это не только lastModified. Есть еще аудит удаленных объектов, хранение истории изменений и так далее. Тоже все это в запрос пихать?

G>>>То что касается бизнес-логики вполне может быть условием в самом запросе

T>>До тех пор, пока бизнес-логика ограничивается простыми правилами.
G>Сложные правила также могут быть выражены в запросах, которые выполняются в SQL, а при помощи Linq записаны в коде приложения.

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

G>Но пока все изменения объектов производятся в памяти, то такой подход неэффективен. Вам придется записать все изменения, запустить запросы, осуществляющие валидацию модели, при неуспешном результате откатить транзакцию. Транзакцию и код проверки для этого придется запускать вручную.


Транзакцию и так придется запускать вручную. Операции затрагивающие одну единственную таблицу встречаются чрезвычайно редко.

G>Если все изменения данных выполняются реляционными операторами и бизнес-правила выражены запросами, то все запросы можно выполнить в одной транзакции БД (при этом практически не тянуть в память объекты), при этом вопросами целостности и конкуретного доступа к данным будет заниматься БД.


А почему в случае UoW она не может заняться вопросами целостности и конкурентного дотупа?

G>>>или проверяться до обращения к данным.

T>>Где? В каком слое приложения?
G>В PL — проверка введенных данных и в BLL — проверка агрументов и параметров окружения.

PL — это что? страница, форма. А если у BLL несколько пользователей? Например, UI и веб-сервис?
Re[10]: Некоторые мысли о LINQ
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 06.01.09 00:54
Оценка:
Здравствуйте, Tissot, Вы писали:

T>Здравствуйте, gandjustas, Вы писали:


T>>>Я видимо не до конца понимаю, что имеется в виду.

T>>>Наследование, интерфейсы, методы, атрибуты — для меня это удобства, от которых я бы очень не хотел отказываться.
G>>Не отказывайтесь. Но базовая модель для данных — ER (потому что БД так работает) и объектная модель должна при желании надстраиваться над ER, причем все "прелести" как ленивая загрузка должны быть опциональны и по-умолчанию выключены.

T>Может поподробней описать, что имеется в виду? В реляционной модели не поддерживаются такие понятия, как наследование, область видимости для данных, методы, меняющие состояние entity. Если все это привнести в нее, то это будет не реляционная, а вполне себе объектная модель.


Подсказка: EDM в EF — практически ER описание, пригодное для использования в программе на .NET. Вполне поддерживается и наследование, и область видимости. Методы, меняющие состояние, вы вполне можете сделать через extensionы.
Вы вообще путаете суть и форму. Классы и объекты — это форма, суть в том что в случае EDM это описание сильно соответствует ER описанию.
С помощью Linq вы можете строить выборки данных с помощью синтаксиса классов и объектов не имея фактически объектов (их состояния) в памяти.


T>>>Не забывай добавлять "в простых (а потому нежизненных) сценарих". Все равно нужно будет делать валидацию/проверку прав/аудит, тут-то объект у вас в память и заползет.

G>>Да ну? Как раз security можно создать дополнительными фильтрами выборки. В моих проектах так и делается, при выборке в память не тянутся объекты для которых доступа нету.
G>>При записи все равно приходится вытягивать нужный объект(с теми же secutiry фильтрами). При наличии операторов update\delete теже фильтры перекочевали бы в соответствующие запросы и не было бы необходимости тянуть целый объект.

T>Тогда бы написание этих запросов превратилось в сущий ад. В лес такое счастье.

С появлением Linq написание выборок гораздо упростилось, сейчас многих уже и не заставишь вложенные циклы писать вместо использования Linq. С чего вы взяли что при расширении Linq операторами insert, update, delete написание запросов превратится в ад?
Пример (гипотетический)
var someQuery = from el in collection where ... select c;//такое уже есть
delete from c in collection where ... //Сложно?
update c in collection where ... set c.Prop1 = val1, c.Prop2 = val2 //Тоже не очень мудрено
insert into collection2 (someQuery) //любое выражение типа IEnumerable<T> в скобках

Где здесь ад? Большая часть уже сделана в Linq запросах, добавить осталось совсем немного.

T>>>>>Де-факто, прежде чем изменить что-то в базе понадобится еще сделать валидацию, поправить информацию о дате последнего изменения, изменить зависимые данные и так далее и тому подобное.

G>>>>То что касается целостности данных должно находится в БД и все проверки и изменения должны осуществляться самой БД.
T>>>Ну приплыли.
G>>Ну не знаю как у вас, а у меня так работает. И отлично работает, по поводу lastModified вообще никто не парится.

T>Аудит — это не только lastModified.

Бывает.

T>Есть еще аудит удаленных объектов,

View + instead of delete триггер

T>хранение истории изменений и так далее.

триггеры

T>Тоже все это в запрос пихать?

Не стоит. Этим должна БД заниматься, причем прозрачно для пользователя.

G>>>>То что касается бизнес-логики вполне может быть условием в самом запросе

T>>>До тех пор, пока бизнес-логика ограничивается простыми правилами.
G>>Сложные правила также могут быть выражены в запросах, которые выполняются в SQL, а при помощи Linq записаны в коде приложения.

T>Теоретически они могут быть туда записаны. А на практике правила зачастую настолько сложны, что что их даже в императивном варианте записать непросто.

В таком случае надо разбивать на более простые... ну как обычно.

G>>Но пока все изменения объектов производятся в памяти, то такой подход неэффективен. Вам придется записать все изменения, запустить запросы, осуществляющие валидацию модели, при неуспешном результате откатить транзакцию. Транзакцию и код проверки для этого придется запускать вручную.


T>Транзакцию и так придется запускать вручную. Операции затрагивающие одну единственную таблицу встречаются чрезвычайно редко.

Также как и вручную вызыыать SaveChanges. Только немного по-другому рабоать будет. В случае работы с объектами вы сначала получаете их из базы, производите операции (при этом пройти может бесконечно много времени), потом пишете в базу изменения.
В случае работы с запросами вы формируете запросы: создаете выборки без материализации записей, подставляете эти выборки в выражения insert\update\delete, в конце батча добавляете запросы, обеспечивающие валидацию, а потом запускаете батч на исполнение. О всем остальном заботится БД.

G>>Если все изменения данных выполняются реляционными операторами и бизнес-правила выражены запросами, то все запросы можно выполнить в одной транзакции БД (при этом практически не тянуть в память объекты), при этом вопросами целостности и конкуретного доступа к данным будет заниматься БД.

T>А почему в случае UoW она не может заняться вопросами целостности и конкурентного дотупа?
Синклер привел пример по этому поводу, прочитайте его повнимательнее.

G>>>>или проверяться до обращения к данным.

T>>>Где? В каком слое приложения?
G>>В PL — проверка введенных данных и в BLL — проверка агрументов и параметров окружения.

T>PL — это что? страница, форма. А если у BLL несколько пользователей? Например, UI и веб-сервис?

Вы не умеете делать валидацию введенных данных?
Re[10]: Некоторые мысли о LINQ
От: VGn Россия http://vassilsanych.livejournal.com
Дата: 06.01.09 01:34
Оценка:
G>>Не отказывайтесь. Но базовая модель для данных — ER (потому что БД так работает) и объектная модель должна при желании надстраиваться над ER, причем все "прелести" как ленивая загрузка должны быть опциональны и по-умолчанию выключены.

T>Может поподробней описать, что имеется в виду? В реляционной модели не поддерживаются такие понятия, как наследование, область видимости для данных, методы, меняющие состояние entity. Если все это привнести в нее, то это будет не реляционная, а вполне себе объектная модель.


А зачем?
SOA тоже хреново поддерживает ООП и интерфейсы, а в версии MS не поддерживает СПЕЦИАЛЬНО,
однако это не мешает ей быть лидирующей технологией для определённого круга задач.
Чем ER хуже?
Или у тебя есть супермолоток?
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Re[11]: Некоторые мысли о LINQ
От: Tissot Россия  
Дата: 06.01.09 01:50
Оценка:
Здравствуйте, gandjustas, Вы писали:

T>>Может поподробней описать, что имеется в виду? В реляционной модели не поддерживаются такие понятия, как наследование, область видимости для данных, методы, меняющие состояние entity. Если все это привнести в нее, то это будет не реляционная, а вполне себе объектная модель.


G>Подсказка: EDM в EF — практически ER описание, пригодное для использования в программе на .NET. Вполне поддерживается и наследование, и область видимости. Методы, меняющие состояние, вы вполне можете сделать через extensionы.

G>Вы вообще путаете суть и форму. Классы и объекты — это форма, суть в том что в случае EDM это описание сильно соответствует ER описанию.

Еще раз, в ER модели нет понятий наследования, области видимости, методов и т.д. Вы очень неудачно пользуетесь терминами, которые имеют вполне определенное значение. Посмотрите в википедии.

G>>>При записи все равно приходится вытягивать нужный объект(с теми же secutiry фильтрами). При наличии операторов update\delete теже фильтры перекочевали бы в соответствующие запросы и не было бы необходимости тянуть целый объект.


T>>Тогда бы написание этих запросов превратилось в сущий ад. В лес такое счастье.

G>С появлением Linq написание выборок гораздо упростилось, сейчас многих уже и не заставишь вложенные циклы писать вместо использования Linq. С чего вы взяли что при расширении Linq операторами insert, update, delete написание запросов превратится в ад?
G>Пример (гипотетический)
G>
G>var someQuery = from el in collection where ... select c;//такое уже есть
G>delete from c in collection where ... //Сложно?
G>update c in collection where ... set c.Prop1 = val1, c.Prop2 = val2 //Тоже не очень мудрено
G>insert into collection2 (someQuery) //любое выражение типа IEnumerable<T> в скобках
G>

G>Где здесь ад? Большая часть уже сделана в Linq запросах, добавить осталось совсем немного.

Ничего сложного, но где здесь security, валидация, аудит?

T>>>>Ну приплыли.

G>>>Ну не знаю как у вас, а у меня так работает. И отлично работает, по поводу lastModified вообще никто не парится.

T>>Аудит — это не только lastModified.

G>Бывает.

T>>Есть еще аудит удаленных объектов,

G>View + instead of delete триггер


T>>хранение истории изменений и так далее.

G>триггеры

T>>Тоже все это в запрос пихать?

G>Не стоит. Этим должна БД заниматься, причем прозрачно для пользователя.

Как понять в триггере, что запись изменил не sa, а "Васиий Петров"?
Что будем делать если нужны осмысленные записи в логе?
Как все это потом тестировать?

T>>Теоретически они могут быть туда записаны. А на практике правила зачастую настолько сложны, что что их даже в императивном варианте записать непросто.

G>В таком случае надо разбивать на более простые... ну как обычно.

Твоими бы устами ...

G>>>Но пока все изменения объектов производятся в памяти, то такой подход неэффективен. Вам придется записать все изменения, запустить запросы, осуществляющие валидацию модели, при неуспешном результате откатить транзакцию. Транзакцию и код проверки для этого придется запускать вручную.


T>>Транзакцию и так придется запускать вручную. Операции затрагивающие одну единственную таблицу встречаются чрезвычайно редко.

G>Также как и вручную вызыыать SaveChanges. Только немного по-другому рабоать будет. В случае работы с объектами вы сначала получаете их из базы, производите операции (при этом пройти может бесконечно много времени), потом пишете в базу изменения.

Тогда я не понимаю, зачем вы писали "все запросы можно выполнить в одной транзакции БД"?
Зачем это подчеркивать, если и так в обоих случаях все будет работать аналогично?

G>В случае работы с запросами вы формируете запросы: создаете выборки без материализации записей, подставляете эти выборки в выражения insert\update\delete, в конце батча добавляете запросы, обеспечивающие валидацию, а потом запускаете батч на исполнение. О всем остальном заботится БД.


Хорошо, хотя бы на уровне псевдокода опиши как это будет выглядеть без материализации данных из базы для следующего сценария:
Если кастомер из категории VIP, то для него должно быть разрешено резервировать заказ на складе без проверок остатков.

G>>>Если все изменения данных выполняются реляционными операторами и бизнес-правила выражены запросами, то все запросы можно выполнить в одной транзакции БД (при этом практически не тянуть в память объекты), при этом вопросами целостности и конкуретного доступа к данным будет заниматься БД.

T>>А почему в случае UoW она не может заняться вопросами целостности и конкурентного дотупа?
G>Синклер привел пример по этому поводу, прочитайте его повнимательнее.

Спасибо, я прочитал. И даже ответил.

G>>>>>или проверяться до обращения к данным.

T>>>>Где? В каком слое приложения?
G>>>В PL — проверка введенных данных и в BLL — проверка агрументов и параметров окружения.

T>>PL — это что? страница, форма. А если у BLL несколько пользователей? Например, UI и веб-сервис?

G>Вы не умеете делать валидацию введенных данных?

А речь не обо мне, а о вашей архитектуре. Где будет происходить валидация.
Предвидя ваш ответ, чуть усложним постановку: модуль A используется модулем B, модуль B создает новый объект в модуле A. Кто должен будет проверить валидность созданного объекта?
Re[12]: Некоторые мысли о LINQ
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 06.01.09 02:40
Оценка:
Здравствуйте, Tissot, Вы писали:

T>Здравствуйте, gandjustas, Вы писали:


T>>>Может поподробней описать, что имеется в виду? В реляционной модели не поддерживаются такие понятия, как наследование, область видимости для данных, методы, меняющие состояние entity. Если все это привнести в нее, то это будет не реляционная, а вполне себе объектная модель.


G>>Подсказка: EDM в EF — практически ER описание, пригодное для использования в программе на .NET. Вполне поддерживается и наследование, и область видимости. Методы, меняющие состояние, вы вполне можете сделать через extensionы.

G>>Вы вообще путаете суть и форму. Классы и объекты — это форма, суть в том что в случае EDM это описание сильно соответствует ER описанию.

T>Еще раз, в ER модели нет понятий наследования, области видимости, методов и т.д. Вы очень неудачно пользуетесь терминами, которые имеют вполне определенное значение. Посмотрите в википедии.


Еще раз. Не путайте суть и форму. Форма будет одинаковая: классы, объекты, интерфесы, наследование. При ООП подходе у вас будет императивный код работы с объектами. При ER — декларативный код работы с сущностями.

G>>>>При записи все равно приходится вытягивать нужный объект(с теми же secutiry фильтрами). При наличии операторов update\delete теже фильтры перекочевали бы в соответствующие запросы и не было бы необходимости тянуть целый объект.


T>>>Тогда бы написание этих запросов превратилось в сущий ад. В лес такое счастье.

G>>С появлением Linq написание выборок гораздо упростилось, сейчас многих уже и не заставишь вложенные циклы писать вместо использования Linq. С чего вы взяли что при расширении Linq операторами insert, update, delete написание запросов превратится в ад?
G>>Пример (гипотетический)
G>>
G>>var someQuery = from el in collection where ... select c;//такое уже есть
G>>delete from c in collection where ... //Сложно?
G>>update c in collection where ... set c.Prop1 = val1, c.Prop2 = val2 //Тоже не очень мудрено
G>>insert into collection2 (someQuery) //любое выражение типа IEnumerable<T> в скобках
G>>

G>>Где здесь ад? Большая часть уже сделана в Linq запросах, добавить осталось совсем немного.

T>Ничего сложного, но где здесь security, валидация, аудит?

Дополнительное выражение в where, или дополнительный запрос.
Или вы считаете что нельзя с помощью запросов выразить большенство операций?

T>Как понять в триггере, что запись изменил не sa, а "Васиий Петров"?

T>Что будем делать если нужны осмысленные записи в логе?
T>Как все это потом тестировать?
Для осмысленных записей в логе в БД есть таблица с пользователями.

Тестировать — спокойно. Создаете пустую базу, выполняете операцию, сверяете запись в логе с эталонной.

G>>>>Но пока все изменения объектов производятся в памяти, то такой подход неэффективен. Вам придется записать все изменения, запустить запросы, осуществляющие валидацию модели, при неуспешном результате откатить транзакцию. Транзакцию и код проверки для этого придется запускать вручную.


T>>>Транзакцию и так придется запускать вручную. Операции затрагивающие одну единственную таблицу встречаются чрезвычайно редко.

G>>Также как и вручную вызыыать SaveChanges. Только немного по-другому рабоать будет. В случае работы с объектами вы сначала получаете их из базы, производите операции (при этом пройти может бесконечно много времени), потом пишете в базу изменения.

T>Тогда я не понимаю, зачем вы писали "все запросы можно выполнить в одной транзакции БД"?

T>Зачем это подчеркивать, если и так в обоих случаях все будет работать аналогично?
Вы не поняли. Действительно можно будет выполнить ВСЕ запросы в одной транзакции. При использовании ОРМ придется сделать выборку в одной транзакции, а потом коммит в другой. Можно явно объявить TransactionScope, но тогда её придется явно завершить после вызова SaveChanges.

G>>В случае работы с запросами вы формируете запросы: создаете выборки без материализации записей, подставляете эти выборки в выражения insert\update\delete, в конце батча добавляете запросы, обеспечивающие валидацию, а потом запускаете батч на исполнение. О всем остальном заботится БД.

T>Хорошо, хотя бы на уровне псевдокода опиши как это будет выглядеть без материализации данных из базы для следующего сценария:
T>Если кастомер из категории VIP, то для него должно быть разрешено резервировать заказ на складе без проверок остатков.

//Предположим что здесь запрос, выполняющий резервирование
//Выборка кастомера, материализация не требуется
var cust = from c in context.Customers 
           where c.Id == customerId
           where c.Category.Name == "VIP"
           select c;

//Теперь валидационный запрос, выполняется в тойже транзакции что и предыдущие
from ..... //Выборка зарезервированных позиций
where (условие остатки < 0) && !cust.Any()
select context.ThrowError() //context.ThrowError - функция в БД, которая кидает ошибку и откатывает транзакцию.


При материализации последнего запроса вылетит ошибка и транзакция будет откачена если остатки ушли в минус, а кастомер не VIP.

G>>>>>>или проверяться до обращения к данным.

T>>>>>Где? В каком слое приложения?
G>>>>В PL — проверка введенных данных и в BLL — проверка агрументов и параметров окружения.

T>>>PL — это что? страница, форма. А если у BLL несколько пользователей? Например, UI и веб-сервис?

G>>Вы не умеете делать валидацию введенных данных?

T>А речь не обо мне, а о вашей архитектуре. Где будет происходить валидация.

T>Предвидя ваш ответ, чуть усложним постановку: модуль A используется модулем B, модуль B создает новый объект в модуле A. Кто должен будет проверить валидность созданного объекта?
Ниче не понял.. Циклические зависимости или как? По-русски опишите чего надо.
Я обычно валидацию на всех уровнях делаю: проверки значений полей ввода в интерфейсе, проверки параметром методов в BLL, валидация модели, констрейнты в БД.
Re[13]: Некоторые мысли о LINQ
От: Tissot Россия  
Дата: 06.01.09 03:12
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>>>Вы вообще путаете суть и форму. Классы и объекты — это форма, суть в том что в случае EDM это описание сильно соответствует ER описанию.


T>>Еще раз, в ER модели нет понятий наследования, области видимости, методов и т.д. Вы очень неудачно пользуетесь терминами, которые имеют вполне определенное значение. Посмотрите в википедии.


G>Еще раз. Не путайте суть и форму. Форма будет одинаковая: классы, объекты, интерфесы, наследование. При ООП подходе у вас будет императивный код работы с объектами. При ER — декларативный код работы с сущностями.


Ок. Я понял, под er вы подразумеваете не er-модель. Проехали.

T>>Ничего сложного, но где здесь security, валидация, аудит?

G>Дополнительное выражение в where, или дополнительный запрос.
G>Или вы считаете что нельзя с помощью запросов выразить большенство операций?

Можно. Но мне не известо ничего о том как бороться со сложностью в запросах. А они при предлагаемых методах будут сложными.

T>>Как понять в триггере, что запись изменил не sa, а "Васиий Петров"?

T>>Что будем делать если нужны осмысленные записи в логе?
T>>Как все это потом тестировать?
G>Для осмысленных записей в логе в БД есть таблица с пользователями.

То есть каждому пользователю давать свой логин в базе? Ты в курсе, что так делать не рекомендуют?

G>Тестировать — спокойно. Создаете пустую базу, выполняете операцию, сверяете запись в логе с эталонной.


Такие тесты работать будут часами. Главное требование к юнит-тесту — это то, что он работает оч. быстро. Станет работать медленно, никто их запускать не будет. На себе проверено.

G>>>>>Но пока все изменения объектов производятся в памяти, то такой подход неэффективен. Вам придется записать все изменения, запустить запросы, осуществляющие валидацию модели, при неуспешном результате откатить транзакцию. Транзакцию и код проверки для этого придется запускать вручную.


T>>>>Транзакцию и так придется запускать вручную. Операции затрагивающие одну единственную таблицу встречаются чрезвычайно редко.

G>>>Также как и вручную вызыыать SaveChanges. Только немного по-другому рабоать будет. В случае работы с объектами вы сначала получаете их из базы, производите операции (при этом пройти может бесконечно много времени), потом пишете в базу изменения.

T>>Тогда я не понимаю, зачем вы писали "все запросы можно выполнить в одной транзакции БД"?

T>>Зачем это подчеркивать, если и так в обоих случаях все будет работать аналогично?
G>Вы не поняли. Действительно можно будет выполнить ВСЕ запросы в одной транзакции. При использовании ОРМ придется сделать выборку в одной транзакции, а потом коммит в другой.

Это еще почему?

G>Можно явно объявить TransactionScope, но тогда её придется явно завершить после вызова SaveChanges.


Это сложно?

G>>>В случае работы с запросами вы формируете запросы: создаете выборки без материализации записей, подставляете эти выборки в выражения insert\update\delete, в конце батча добавляете запросы, обеспечивающие валидацию, а потом запускаете батч на исполнение. О всем остальном заботится БД.

T>>Хорошо, хотя бы на уровне псевдокода опиши как это будет выглядеть без материализации данных из базы для следующего сценария:
T>>Если кастомер из категории VIP, то для него должно быть разрешено резервировать заказ на складе без проверок остатков.

G>
G>//Предположим что здесь запрос, выполняющий резервирование
G>//Выборка кастомера, материализация не требуется
G>var cust = from c in context.Customers 
G>           where c.Id == customerId
G>           where c.Category.Name == "VIP"
G>           select c;

G>//Теперь валидационный запрос, выполняется в тойже транзакции что и предыдущие
G>from ..... //Выборка зарезервированных позиций
G>where (условие остатки < 0) && !cust.Any()
G>select context.ThrowError() //context.ThrowError - функция в БД, которая кидает ошибку и откатывает транзакцию.
G>


G>При материализации последнего запроса вылетит ошибка и транзакция будет откачена если остатки ушли в минус, а кастомер не VIP.


То есть сначала мы пишем в базу, а потом валидируем? Оригинально
Это точно ты говорил, что материализация плохо отражается на перформансе?

T>>>>PL — это что? страница, форма. А если у BLL несколько пользователей? Например, UI и веб-сервис?

G>>>Вы не умеете делать валидацию введенных данных?

T>>А речь не обо мне, а о вашей архитектуре. Где будет происходить валидация.

T>>Предвидя ваш ответ, чуть усложним постановку: модуль A используется модулем B, модуль B создает новый объект в модуле A. Кто должен будет проверить валидность созданного объекта?
G>Ниче не понял.. Циклические зависимости или как? По-русски опишите чего надо.

Пусть система состоит из 2-х подсистем: работа с кастомерами, база знаний.
Есть кастомер. При регистрации его в системе должен создаться соответствующий раздел в базе знаний.
Где (кем) будет проверяться, что созданный раздел создан корректно?

G>Я обычно валидацию на всех уровнях делаю: проверки значений полей ввода в интерфейсе, проверки параметром методов в BLL, валидация модели, констрейнты в БД.


Два сообщения назад валидации модели еще не было. Прогресс налицо!

P.S. На самом деле то, что вы описываете, до боли напоминает transaction script как он назван у Фаулера. Единственное отличие, которое я вижу — это его типизированность. В той же книжке описывается почему с ростом сложности приложения с transaction script-ом становится сложно жить. Рекомендую глянуть, если еще не смотрели.
Re[11]: Некоторые мысли о LINQ
От: Tissot Россия  
Дата: 06.01.09 03:15
Оценка:
Здравствуйте, VGn, Вы писали:

T>>Может поподробней описать, что имеется в виду? В реляционной модели не поддерживаются такие понятия, как наследование, область видимости для данных, методы, меняющие состояние entity. Если все это привнести в нее, то это будет не реляционная, а вполне себе объектная модель.


VGn>А зачем?


За надом (понимать буквально)

VGn>SOA тоже хреново поддерживает ООП и интерфейсы, а в версии MS не поддерживает СПЕЦИАЛЬНО,

VGn>однако это не мешает ей быть лидирующей технологией для определённого круга задач.
VGn>Чем ER хуже?

Причину отсутствия этого в SOA вполне можно понять. Зачем отказываться от этого в domain model я не понимаю.
Re[8]: Некоторые мысли о LINQ
От: Sinclair Россия https://github.com/evilguest/
Дата: 06.01.09 07:43
Оценка:
Здравствуйте, Tissot, Вы писали:

T>Вот как раз в случае UoW удержание будет меньше.

Непонятно, за счёт чего.
T>Рассмотри сценарий чуть посложнее, чем "обновить поле". Например в результате какой-то операции сначала нам понадобилось обновить у сustome-а поле A, потом провести какие-то достаточно длительные вычисления, потом обновить поле B.
Я такой сценарий представляю себе с большим трудом.
T>В варианте с UoW на время операции будет наложена shared блокировка и только на время submit-а — более тяжелая exclusive.
А ничего, что в случае отката транзакции значение поля А, прочитанное кем-то во время "удержания shared блокировки", будет потеряно?

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

T>Очень интересно. Откуда же сервер узнает, что блокировку можно отпустить, что она более не понадобится?



S>>А теперь посмотрим, как бы это работало без Full Blown O/R mapper.

S>>В старые добрые времена программист БД просто написал бы один запрос вида:
S>>
S>>update StoreItem set Available = Available - OrderItem.Amount, Reserved = Reserved + OrderItem.Amount
S>>from StoreItem inner join OrderItem on StoreItem.ProductID = OrderItem.ProductId
S>>where OrderItem.OrderID = @OrderId and StoreItem.Available >= OrderItem.Amount;
S>>

S>>Сервер бы сам проследил за целостностью транзакции, не давая Кате модифицировать накладную в процессе резервирования. (Обеспечение запрета модифицировать накладную после резервирования потребовало бы чуть больше приседаний, но в чистом Оптимистично Блокированном мире это вообще невозможно без лишних телодвижений).

T>Во-первых, вы допустили ошибку в коде.

Где?
T>Во-вторых, на самом деле все может быть сложнее: для каких-то категорий клиентов/товаров вполне может быть позволено заказывать в минуса, для каких-то категорий товаров должен гарантировано оставаться какой-то остаток на складах, если заказ крупный, то должно быть проверено, внесена ли предоплата и т.д. и т.п.. Я бы не хотел поддерживать код в котором все эти правила внесены в один update.
Именно облегчения поддержки такого кода мы и ждем от Linq. Потому, что вручную педалить все эти вещи — очень тяжело, и мы хотим контроль компилятора. Вот select стейтменты линк готовит прекрасно. Можно иметь произвольно сложную логику по динамическому формированию предикатов и всё еще получать статический контроль корректности.

T>Фишка в том, что это не код, а фикция.

Это смелое утверждение.
T>Ты забыл добавить "если update — это единственная действие в бизнес-транзакции".
Ну, вообще-то подавляющее большинство "бизнес-операций" сводятся к очень ограниченному набору insert/update/delete. Особенно если проектировать приложение, держа это в уме.
Просто средства и фреймворки всегда навязывают своё мышление. "Реляционный" программист всегда старается свести задачу к манипуляции над реляциями. Как раз такого типа, как я показал. Вот ты привел примеры дополнительных бизнес-правил. "ООПшный" программист постарается избавиться от if-ов, которые проверяют "не нужно ли запасти ненулевой остаток для данной категории товара", и "нужна ли предоплата для данного размера заказа", путём выноса их в виртуальные методы некоторой иерархии классов. А реляционщик попробует свести всё это небольшому количеству массовых апдейтов.
То есть построит отдельную view "минимально допустимый остаток товара на складе" и приджойнит ее к запросу. И так далее.

Я еще раз подчеркиваю, что основное ограничение unit of work — в том, что он следит исключительно за изменениями, сделанными в транзакции. Он ничего не знает о том, какие причины привели к этим изменениям. Это означает, в частности, что для обеспечения элементарной транзакционной целостности, которая доступна в старинном SQL забесплатно, нужно делать специальные приседания.

T>А может зря оно себя таким уж прогрессивным считает?

Видишь ли, в чем дело. Это человечество разрабатывало ORM системы еще до первого коммита в репозиторий Hibernate и выхода Фаулеровского "P of EAA".
И был накоплен некоторый опыт взаимодействия с самыми разными архитектурами систем. Linq — это самое передовое достижение мысли в области работы с реляционными данными, но и у него есть недостатки.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[14]: Некоторые мысли о LINQ
От: Sinclair Россия https://github.com/evilguest/
Дата: 06.01.09 07:57
Оценка:
Здравствуйте, Tissot, Вы писали:
T>Можно. Но мне не известо ничего о том как бороться со сложностью в запросах. А они при предлагаемых методах будут сложными.
Это ключевой момент в данной дискуссии.
Поясняю на пальцах: Linq и есть способ борьбы со сложностью в запросах.
Потому, что вместо кропотливого построения многоэтажных where, можно разбить процесс построения запроса на несколько частей:
storeItems = GetStoreItems(order);
storeItems = AddQuantityCheck(storeItems);
storeItems = AddSecurityCheck(storeItems);

Каждая из них по отдельности проста. А Linq обеспечивает корректную склейку этих частей.
Более того, их можно применять динамически:
storeItems = GetStoreItems(order);
if (customer.Status != CustomerStatus.VIP)
  storeItems = AddQuantityCheck(storeItems);
storeItems = AddSecurityCheck(storeItems);

Вот примерно так и борются со сложностью SQL запросов.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[15]: Некоторые мысли о LINQ
От: Tissot Россия  
Дата: 06.01.09 11:00
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Более того, их можно применять динамически:

S>
S>storeItems = GetStoreItems(order);
S>if (customer.Status != CustomerStatus.VIP)
S>  storeItems = AddQuantityCheck(storeItems);
S>storeItems = AddSecurityCheck(storeItems);
S>

S>Вот примерно так и борются со сложностью SQL запросов.

Ну в общем-то так и думал. Работал с таким — лучше чем ничего, но все равно недостаточно удобно. Если придумаете что-то более удобное — то честь вам и хвала.
Re[14]: Некоторые мысли о LINQ
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 06.01.09 11:15
Оценка:
Здравствуйте, Tissot, Вы писали:

T>Здравствуйте, gandjustas, Вы писали:


G>>>>Вы вообще путаете суть и форму. Классы и объекты — это форма, суть в том что в случае EDM это описание сильно соответствует ER описанию.

T>>>Еще раз, в ER модели нет понятий наследования, области видимости, методов и т.д. Вы очень неудачно пользуетесь терминами, которые имеют вполне определенное значение. Посмотрите в википедии.
G>>Еще раз. Не путайте суть и форму. Форма будет одинаковая: классы, объекты, интерфесы, наследование. При ООП подходе у вас будет императивный код работы с объектами. При ER — декларативный код работы с сущностями.
T>Ок. Я понял, под er вы подразумеваете не er-модель. Проехали.
А что вы подразумеваете под ER моделью в программе?

T>>>Ничего сложного, но где здесь security, валидация, аудит?

G>>Дополнительное выражение в where, или дополнительный запрос.
G>>Или вы считаете что нельзя с помощью запросов выразить большенство операций?
T>Можно. Но мне не известо ничего о том как бороться со сложностью в запросах. А они при предлагаемых методах будут сложными.
Известно. Linq в текущей реализации позоволяет последовательно строить выборку, накладывая дополнительные ограничения.
В коде выглядит как фильрация коллекции с разными условиями, только самой коллекции нету.

T>>>Как понять в триггере, что запись изменил не sa, а "Васиий Петров"?

T>>>Что будем делать если нужны осмысленные записи в логе?
T>>>Как все это потом тестировать?
G>>Для осмысленных записей в логе в БД есть таблица с пользователями.

T>То есть каждому пользователю давать свой логин в базе? Ты в курсе, что так делать не рекомендуют?

Нет, есть таблица, хранящая логины и другие сведения о пользователях. В логах можно ссылкаться на эту таблицу.

G>>Тестировать — спокойно. Создаете пустую базу, выполняете операцию, сверяете запись в логе с эталонной.

T>Такие тесты работать будут часами. Главное требование к юнит-тесту — это то, что он работает оч. быстро. Станет работать медленно, никто их запускать не будет. На себе проверено.
Вам не потребуется эти тесты запускать в совокупноти с unit-тестами приложения. Аудит в БД полностью ортогонален бизнес-логике в коде приложения.

G>>Вы не поняли. Действительно можно будет выполнить ВСЕ запросы в одной транзакции. При использовании ОРМ придется сделать выборку в одной транзакции, а потом коммит в другой.

T>Это еще почему?
Потому что реализация такая. Linq2SQL и EF так работают.

G>>Можно явно объявить TransactionScope, но тогда её придется явно завершить после вызова SaveChanges.

T>Это сложно?
Это сложнее чем ОДИН раз явно обявить транзакцию при использовании запросов.

G>>>>В случае работы с запросами вы формируете запросы: создаете выборки без материализации записей, подставляете эти выборки в выражения insert\update\delete, в конце батча добавляете запросы, обеспечивающие валидацию, а потом запускаете батч на исполнение. О всем остальном заботится БД.

T>>>Хорошо, хотя бы на уровне псевдокода опиши как это будет выглядеть без материализации данных из базы для следующего сценария:
T>>>Если кастомер из категории VIP, то для него должно быть разрешено резервировать заказ на складе без проверок остатков.

G>>
G>>//Предположим что здесь запрос, выполняющий резервирование
G>>//Выборка кастомера, материализация не требуется
G>>var cust = from c in context.Customers 
G>>           where c.Id == customerId
G>>           where c.Category.Name == "VIP"
G>>           select c;

G>>//Теперь валидационный запрос, выполняется в тойже транзакции что и предыдущие
G>>from ..... //Выборка зарезервированных позиций
G>>where (условие остатки < 0) && !cust.Any()
G>>select context.ThrowError() //context.ThrowError - функция в БД, которая кидает ошибку и откатывает транзакцию.
G>>


G>>При материализации последнего запроса вылетит ошибка и транзакция будет откачена если остатки ушли в минус, а кастомер не VIP.


T>То есть сначала мы пишем в базу, а потом валидируем? Оригинально

При таком подходе ВСЯ работа с данными происходит в БД, это нормально.

T>Это точно ты говорил, что материализация плохо отражается на перформансе?

Это так и есть.

T>Пусть система состоит из 2-х подсистем: работа с кастомерами, база знаний.

T>Есть кастомер. При регистрации его в системе должен создаться соответствующий раздел в базе знаний.
T>Где (кем) будет проверяться, что созданный раздел создан корректно?
Наверное тем кто создает раздел. К чему это все?

G>>Я обычно валидацию на всех уровнях делаю: проверки значений полей ввода в интерфейсе, проверки параметром методов в BLL, валидация модели, констрейнты в БД.

T>Два сообщения назад валидации модели еще не было. Прогресс налицо!
Два сообщения назад я говорил о валидации, не касающейся данных в базе.

T>P.S. На самом деле то, что вы описываете, до боли напоминает transaction script как он назван у Фаулера. Единственное отличие, которое я вижу — это его типизированность. В той же книжке описывается почему с ростом сложности приложения с transaction script-ом становится сложно жить. Рекомендую глянуть, если еще не смотрели.

Я уже форуме "архитектура" про фаулера отписал. Повторюсь здесь.
Концептуальная разница между transaction script и dimain model состоит в том как вы хотите вызывать методы бизнес-логики
Так
entity.Operation(params)

или так
service.Operation(entity, params)

Второй подход гораздо лучше по многим причинам.

А фаулер какю-то неправильную траву курит.
Re[9]: Некоторые мысли о LINQ
От: Tissot Россия  
Дата: 06.01.09 11:24
Оценка:
Здравствуйте, Sinclair, Вы писали:

T>>Вот как раз в случае UoW удержание будет меньше.

S>Непонятно, за счёт чего.

См. ниже.

T>>Рассмотри сценарий чуть посложнее, чем "обновить поле". Например в результате какой-то операции сначала нам понадобилось обновить у сustome-а поле A, потом провести какие-то достаточно длительные вычисления, потом обновить поле B.

S>Я такой сценарий представляю себе с большим трудом.

А ты представь.

T>>В варианте с UoW на время операции будет наложена shared блокировка и только на время submit-а — более тяжелая exclusive.

S>А ничего, что в случае отката транзакции значение поля А, прочитанное кем-то во время "удержания shared блокировки", будет потеряно?

Я не совсем интонацию понял. Для меня вопрос звучит столь же нелепо, как и спрашивать — "а ничего, что при откате транзакции изменения потеряются".

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


Нельзя, целостность будет потеряна.

S>А если такое нарушение целостности недопустимо, то UoW нужно срочно выбросить.


Не улавливаю ход рассуждения, распиши подробнее.

S>>>В старые добрые времена программист БД просто написал бы один запрос вида:

S>>>
S>>>update StoreItem set Available = Available - OrderItem.Amount, Reserved = Reserved + OrderItem.Amount
S>>>from StoreItem inner join OrderItem on StoreItem.ProductID = OrderItem.ProductId
S>>>where OrderItem.OrderID = @OrderId and StoreItem.Available >= OrderItem.Amount;
S>>>

S>>>Сервер бы сам проследил за целостностью транзакции, не давая Кате модифицировать накладную в процессе резервирования. (Обеспечение запрета модифицировать накладную после резервирования потребовало бы чуть больше приседаний, но в чистом Оптимистично Блокированном мире это вообще невозможно без лишних телодвижений).

T>>Во-первых, вы допустили ошибку в коде.

S>Где?

Задание на дом. Перечитай свое же сообщение еще раз.

T>>Во-вторых, на самом деле все может быть сложнее: для каких-то категорий клиентов/товаров вполне может быть позволено заказывать в минуса, для каких-то категорий товаров должен гарантировано оставаться какой-то остаток на складах, если заказ крупный, то должно быть проверено, внесена ли предоплата и т.д. и т.п.. Я бы не хотел поддерживать код в котором все эти правила внесены в один update.

S>Именно облегчения поддержки такого кода мы и ждем от Linq. Потому, что вручную педалить все эти вещи — очень тяжело, и мы хотим контроль компилятора. Вот select стейтменты линк готовит прекрасно. Можно иметь произвольно сложную логику по динамическому формированию предикатов и всё еще получать статический контроль корректности.

Вручную педалить тяжело если вы остаетесь в рамках trabsaction script-а. Переходите на ооп подход и волосы становятся густыми и блестящими

T>>Фишка в том, что это не код, а фикция.

S>Это смелое утверждение.
T>>Ты забыл добавить "если update — это единственная действие в бизнес-транзакции".
S>Ну, вообще-то подавляющее большинство "бизнес-операций" сводятся к очень ограниченному набору insert/update/delete. Особенно если проектировать приложение, держа это в уме.
S>Просто средства и фреймворки всегда навязывают своё мышление. "Реляционный" программист всегда старается свести задачу к манипуляции над реляциями. Как раз такого типа, как я показал. Вот ты привел примеры дополнительных бизнес-правил. "ООПшный" программист постарается избавиться от if-ов, которые проверяют "не нужно ли запасти ненулевой остаток для данной категории товара", и "нужна ли предоплата для данного размера заказа", путём выноса их в виртуальные методы некоторой иерархии классов.

Совершенно верно.

S>А реляционщик попробует свести всё это небольшому количеству массовых апдейтов.


Пока у них это не очень хорошо получается. Те средства декомпозиции запросов, что есть в SQL-е и в базах данных (WITH, view, функции) просто смешны и не выдерживают никакой критики.

S>То есть построит отдельную view "минимально допустимый остаток товара на складе" и приджойнит ее к запросу. И так далее.


Как бороться со ложностью? Как это тестировать? и так далее.
ООП дает на эти вопросы более менее внятный ответ.

S>Я еще раз подчеркиваю, что основное ограничение unit of work — в том, что он следит исключительно за изменениями, сделанными в транзакции. Он ничего не знает о том, какие причины привели к этим изменениям. Это означает, в частности, что для обеспечения элементарной транзакционной целостности, которая доступна в старинном SQL забесплатно, нужно делать специальные приседания.


Не пойму, что тебе запрещает использовать танзакции-то? И полчишь "целостность, которая доступна в старинном SQL забесплатно".

T>>А может зря оно себя таким уж прогрессивным считает?

S>Видишь ли, в чем дело. Это человечество разрабатывало ORM системы еще до первого коммита в репозиторий Hibernate и выхода Фаулеровского "P of EAA".
S>И был накоплен некоторый опыт взаимодействия с самыми разными архитектурами систем. Linq — это самое передовое достижение мысли в области работы с реляционными данными, но и у него есть недостатки.

Все новое всегда кажется лучшим и более передовым. Linq-у не так много лет, чтобы успеть обкатать его в достаточной мере и почувствовать на собственной шкуре все недостатки, которых он конечно же не лишен.
Подходу же с linq-like insert-ами — и того меньше лет (0). Поэтому говорить о его достоинствах несколько рановато.
Re[12]: Некоторые мысли о LINQ
От: IB Австрия http://rsdn.ru
Дата: 06.01.09 12:39
Оценка: +1
Здравствуйте, Tissot, Вы писали:

T>За надом (понимать буквально)

То есть, очень хочется, но объяснить не можешь? )

T> Зачем отказываться от этого в domain model я не понимаю.

Потому что там это не нужно и даже вредно.
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re[6]: Некоторые мысли о LINQ
От: IB Австрия http://rsdn.ru
Дата: 06.01.09 12:39
Оценка:
Здравствуйте, Tissot, Вы писали:

T>Не стоит выдавать де-факто стандарт в области разработки корпоративных приложений за мое предпочтение.

Во-первых, де-факто стандарт — это очень сильное преувеличение. А во-вторых, стандартность подхода довольно хлипкий аргумент.

T>Почему вариант с update/insert будет иметь меньшее кол-во блокировок?

Он будет держать их меньшее время и блокировки будут поддаваться большему контролю.

T>Мне доводилось работать с корпоративными приложениями, в том числе с достаточно крупными (Axapta).



T>Конечно-конечно, довод и разряда "все гандоны, а я супер". Продолжай в том же духе.

Это ты про себя сейчас? ) Не надо, не продолжай.
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re[4]: Некоторые мысли о LINQ
От: IB Австрия http://rsdn.ru
Дата: 06.01.09 12:39
Оценка: +1
Здравствуйте, Tissot, Вы писали:

T>Потому что реляционные операторы это — объединение, пересечение, разность, произведение, сокращение, проекция, соединение, деление. Другие в реляционную алгебру не входят.

Я тебе больше скажу, SQL вообще мало отношения к реляционной алгебре имеет. Только работают все с SQL-ем, а не с реляцонной алгеброй в вакууме.
Ты что сказать-то хотел?

T>Я считаю этот вопрос стоит разделить на 2:

T>1) ER vs ObjectModel: мой выбор однозначно в пользу ObjectModel. Потому что она банально предоставляет больше возможностей.
Если бы это было так, то весь мир уже давно бы сидел на ООБД. Правда заключается в том, что большинство возможностей ОО подхода при работе с данными оказываются либо бесполезными, либо вообще вредными.

T> Кроме того, er может быть смоделирована через object model, обратное — неверно.

Приведи мне пример объектов, которые нельзя было бы смоделировать, через ER?

T>2) SQL DML vs unit of work: unit of work в большинстве случаев удобнее и предпочтительнее.

Это в каких, например?

T> Единственный его недостаток — это когда нужно массово обновить большое количество объектов.

Если под "массово обновить большое количество объектов" понимается, что объектов больше одного, то согласен.
Проблема только в том, что таких случаев в реальной жизни подавляющее большинство, отсюда делаем совершенно закономерный вывод, что UoW конструкция бесполезная.
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re[8]: Некоторые мысли о LINQ
От: IB Австрия http://rsdn.ru
Дата: 06.01.09 12:39
Оценка: +1
Здравствуйте, Tissot, Вы писали:

T>В случае, если действуем по вашему сценарию — сразу получаем exclusive и удерживаем ее на время операции.

Это с какого перепуга?

T>И какой вариант после этого более легковесный?

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

T>Очень интересно. Откуда же сервер узнает, что блокировку можно отпустить, что она более не понадобится?

Потому что ему доступна вся транзакция и он может ее оптимизировать так как ему удобно.

T>Во-вторых, на самом деле все может быть сложнее: для каких-то категорий клиентов/товаров вполне может быть позволено заказывать в минуса, для каких-то категорий товаров должен гарантировано оставаться какой-то остаток на складах, если заказ крупный, то должно быть проверено, внесена ли предоплата и т.д. и т.п.. Я бы не хотел поддерживать код в котором все эти правила внесены в один update.

В том-то и дело, что теоретически этот update можно поддерживать легко и непринужденно, если делать это так же, как LINQ позволяет обращаться с select-ом.

T>Фишка в том, что это не код, а фикция.

Это твой основной аргумент? )

T>Ты забыл добавить "если update — это единственная действие в бизнес-транзакции".

Бизнес-транзакция тут непричем. Бизнес-транзакция и транзакция БД — вещи совершенно разные и декларативный подход, при работе с данными дает гораздо больший контроль и над тем что происходит в бизнес-транзакциях и над тем, что происходит в БД.
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re[16]: Некоторые мысли о LINQ
От: IB Австрия http://rsdn.ru
Дата: 06.01.09 12:46
Оценка: +2
Здравствуйте, Tissot, Вы писали:


T>Ну в общем-то так и думал. Работал с таким — лучше чем ничего, но все равно недостаточно удобно. Если придумаете что-то более удобное — то честь вам и хвала.

Достаточно того, что это намного удобнее чем UoW, ORM и прочие приседания вокруг ОО.
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re[9]: Некоторые мысли о LINQ
От: Tissot Россия  
Дата: 06.01.09 14:19
Оценка:
Здравствуйте, IB, Вы писали:

T>>В случае, если действуем по вашему сценарию — сразу получаем exclusive и удерживаем ее на время операции.

IB>Это с какого перепуга?

Потому что update

T>>И какой вариант после этого более легковесный?

IB>конечно сиквельный, так как все тяжелые операции будут сделаны еще до первого обращения к базе, без каких либо блокировок.

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

T>>Очень интересно. Откуда же сервер узнает, что блокировку можно отпустить, что она более не понадобится?

IB>Потому что ему доступна вся транзакция и он может ее оптимизировать так как ему удобно.

Я не знал, что если в батче содержится несколько стейтментов, то сервер анализирует весь батч целиком. Всегда был уверен, что он выполняет стейтмент за стейтментом.
Если у вас другая информация, не мог бы ты подилиться источником оной?

T>>Во-вторых, на самом деле все может быть сложнее: для каких-то категорий клиентов/товаров вполне может быть позволено заказывать в минуса, для каких-то категорий товаров должен гарантировано оставаться какой-то остаток на складах, если заказ крупный, то должно быть проверено, внесена ли предоплата и т.д. и т.п.. Я бы не хотел поддерживать код в котором все эти правила внесены в один update.

IB>В том-то и дело, что теоретически этот update можно поддерживать легко и непринужденно, если делать это так же, как LINQ позволяет обращаться с select-ом.

Ключевое слово выделено. А на практике?

T>>Фишка в том, что это не код, а фикция.

IB>Это твой основной аргумент? )

А как еще назвать ситуацию, когда в качестве аргумента приводят код, который в жизни практически не встречается?

T>>Ты забыл добавить "если update — это единственная действие в бизнес-транзакции".

IB>Бизнес-транзакция тут непричем.

Я в курсе. Под бизнес-транзакцией в данном случае я имел в виду некоторое действие производимое с системой атомарное с точки зрения пользователя. Не смог подобрать более подходящего названия.
Приведенный код был слишком простым, чтобы на его примере увидить недостатки подхода "делаем все одним update-ом". Де-факто этот единственный update потребует как минимум проверку валидности, проверку безопасности, аудит действий и т.д. Если бы все эти сервисные операции были включены в пример, то его красота сразу бы куда-то улетучилась.

IB>Бизнес-транзакция и транзакция БД — вещи совершенно разные и декларативный подход, при работе с данными дает гораздо больший контроль и над тем что происходит в бизнес-транзакциях и над тем, что происходит в БД.


Очень интересный тезис, но позволь в него не поверить. Ну или по-крайней мере объясни откуда возьмется этот больший контроль.
Re[7]: Некоторые мысли о LINQ
От: Tissot Россия  
Дата: 06.01.09 14:28
Оценка:
Здравствуйте, IB, Вы писали:

T>>Не стоит выдавать де-факто стандарт в области разработки корпоративных приложений за мое предпочтение.

IB>Во-первых, де-факто стандарт — это очень сильное преувеличение.

Я довольно регулярно слежу за тенденциями в этой сфере. И мне как-то последние годов несколько очень редко попадаются апологеты подхода "запихнем все в базу". Все больше как-то говорят за полноценную domain model.
Но не исключаю, что я что-то упустил. Буду благодарен, если подкинешь ссылочек.

IB>А во-вторых, стандартность подхода довольно хлипкий аргумент.


Стандартность означает распространенность, распространенность означает что большинство граблей уже найдено и найдены способы как с ними бороться.
В сухом остатке получаем, что подход с domain model более "проработан" чем иные.
Это тоже будешь считать более хлипким аргументом?

T>>Почему вариант с update/insert будет иметь меньшее кол-во блокировок?

IB>Он будет держать их меньшее время и блокировки будут поддаваться большему контролю.

Я же привел пример:
1. делаем update 1 поля
2. долго что-то считаем
3. делаем следующий update

Не мог бы ты оставаясь в рамках этого примера описать, откуда возникнет "меньшее время" и "больший контроль"?

T>>Мне доводилось работать с корпоративными приложениями, в том числе с достаточно крупными (Axapta).

IB>

Что тебя так развеселило? Расскажи, вместе посмеемся.
Re[17]: Некоторые мысли о LINQ
От: Tissot Россия  
Дата: 06.01.09 14:29
Оценка:
Здравствуйте, IB, Вы писали:

T>>Ну в общем-то так и думал. Работал с таким — лучше чем ничего, но все равно недостаточно удобно. Если придумаете что-то более удобное — то честь вам и хвала.

IB>Достаточно того, что это намного удобнее чем UoW, ORM и прочие приседания вокруг ОО.

Спасибо за развернутый и аргуметированный ответ. Вы раскрыли мне глаза.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.