|
NHibernate Unit of Work и UI
|
|||
---|---|---|---|
#18+
Доброго вечера всем. Есть окно (Win Application), состоящее из двух фреймов: слева список (ListBox) сотрудников (класс Person), а справа детальная информация (свойства класса Person). Когда пользователь выбирает сотрудника в списке, я открываю сессию NHibernate и по его имени запрашиваю объект Person из БД, закрываю сессию и затем визуализирую данные о сотруднике в правом окне. Правое окно содержит также список детей сотрудника (List<Child>), соответственно по нажатии на кнопку "Сохранить" я открываю сессию, сновазапрашиваю сотрудника по имени и с полученным Person уже выполняю изменения: обновление полей на основе данных в полях формы, а список детей редактирую вручную: т.е. синхронизирую данные формыс данными Person.Children, считая, что первичнее данные формы. В этом варианте, я не могу использовать привязку. Порочна ли такая практика? ... |
|||
:
Нравится:
Не нравится:
|
|||
22.03.2012, 22:08 |
|
NHibernate Unit of Work и UI
|
|||
---|---|---|---|
#18+
CVlasovПорочна ли такая практика? Да. Куча бесполезных запросов к БД. Правильный вариант выглядит так: 1. При открытии списка открываем сессии, и запрашиваем проекцию списка пользователей, отображаем ее. 2. Когда юзер о открывает пользователя на редактирование, передаём редактирующем окну id-пользователя, открываем в нём новую сессию, и одним запросом тянем сотрудника со всеми его детьми. 3. В процессе редактирования сессия висит открытая. 4. Когда пользователь нажимает сохранить, вызываем session.Flush(), и закрываем ее. 5. Передаём в окно со списком обновлённые данные по сотруднику (без запроса в БД), если на прошлом шаге изменения были успешно сохранены. ... |
|||
:
Нравится:
Не нравится:
|
|||
23.03.2012, 11:32 |
|
NHibernate Unit of Work и UI
|
|||
---|---|---|---|
#18+
Так ли уж критично, открывать сессию при запросе из списка, или при создании окна. Как сама сессия, это легковесный продукт, и пока мы ей не работаем, сессия никакой угрозы для памяти не представляет нет соединений, не открыты транзакции единицы работы, пустой кеш и тд...? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.03.2012, 00:48 |
|
NHibernate Unit of Work и UI
|
|||
---|---|---|---|
#18+
SolYUtor2. Когда юзер о открывает пользователя на редактирование, передаём редактирующем окну id-пользователя, открываем в нём новую сессию, и одним запросом тянем сотрудника со всеми его детьми. 3. В процессе редактирования сессия висит открытая. 4. Когда пользователь нажимает сохранить, вызываем session.Flush(), и закрываем ее. 5. Передаём в окно со списком обновлённые данные по сотруднику (без запроса в БД), если на прошлом шаге изменения были успешно сохранены. А если в процессе сохранения возникли ошибки и изменения не сохранены? Объекты POCO привязаны к контролам, что делать в этой ситуации? Все изменения, внесенные пользователем, потеряются и нужно перезагрузить Person из БД? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.03.2012, 09:05 |
|
NHibernate Unit of Work и UI
|
|||
---|---|---|---|
#18+
CVlasov, немного не понятно, персон самодостаточный обьект, он все знает про себя и как оно лежит в базе, он отвязан от сессии. при нарушении, он не пропадает, зачем его перегружать например обрыв связи? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.03.2012, 12:54 |
|
NHibernate Unit of Work и UI
|
|||
---|---|---|---|
#18+
Где-то в степиCVlasov, немного не понятно, персон самодостаточный обьект, он все знает про себя и как оно лежит в базе, он отвязан от сессии. при нарушении, он не пропадает, зачем его перегружать например обрыв связи? Т.е. я могу повторно запустить транзакцию и вызвать Flush? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.03.2012, 22:37 |
|
NHibernate Unit of Work и UI
|
|||
---|---|---|---|
#18+
CVlasov, если сессия в рабочем виде, до да, при откате откатываются служебные настройки объекта персистентность, флаг изменения, пользовательские не трогаются ... |
|||
:
Нравится:
Не нравится:
|
|||
24.03.2012, 23:20 |
|
NHibernate Unit of Work и UI
|
|||
---|---|---|---|
#18+
Где-то в степиCVlasov, если сессия в рабочем виде, до да, при откате откатываются служебные настройки объекта персистентность, флаг изменения, пользовательские не трогаются Т.е.: 1. Открываем сессию. 2. Открываем транзакцию. 3. Загружаем Person в сессию со всеми связанными подчиненными записями (несколько списков: дети, история должностей, выплаченные премии и т.п.). 4. Закрываем транзакцию. 5. Привязываем Person к контролам. 6. Пользователь редактирует Person. Если нужно загрузить справочник, то опять запускаем транзакцию, загружаем в сессию записи справочника, закрываем транзакцию, выводим записи в ListBox и опять работаем только с Person. 7. Пользователь пытается сохранить Person. Запускаем транзакцию, вызываем Save(Person). Возникает исключение - имена дублируются. Откатывает транзакцию, меняем имя на корректное, снова запускаем транзакцию, фиксируем ее. А если потомки Person'а замаплены как Cascade.AllDeleteOrphan, будет работать. Перефразируя вышесказанное: я могу использовать одну сессию для повторного сохранения, если первая транзакция была откачена? P.S. Есть простой способ реализовать INotifyPropertyChanged в POCO-классах, таких как Person? ... |
|||
:
Нравится:
Не нравится:
|
|||
25.03.2012, 09:48 |
|
NHibernate Unit of Work и UI
|
|||
---|---|---|---|
#18+
CVlasovПерефразируя вышесказанное: я могу использовать одну сессию для повторного сохранения, если первая транзакция была откачена? Не во всех случаях. Если случится StaleObjectStateException - то сессия будет кидаться исключениями при попытке любых действий с ней. В таком случае надо открывать новую сессию, и делать Merge. Это сохранит изменения, сделанные в вашем объекте. CVlasovP.S. Есть простой способ реализовать INotifyPropertyChanged в POCO-классах, таких как Person? Есть отличный способ . ... |
|||
:
Нравится:
Не нравится:
|
|||
26.03.2012, 10:03 |
|
NHibernate Unit of Work и UI
|
|||
---|---|---|---|
#18+
SolYUtorCVlasovПерефразируя вышесказанное: я могу использовать одну сессию для повторного сохранения, если первая транзакция была откачена? Не во всех случаях. Если случится StaleObjectStateException - то сессия будет кидаться исключениями при попытке любых действий с ней. В таком случае надо открывать новую сессию, и делать Merge. Это сохранит изменения, сделанные в вашем объекте. CVlasovP.S. Есть простой способ реализовать INotifyPropertyChanged в POCO-классах, таких как Person? Есть отличный способ . Про Merge я не знал. Может, тогда подскажете как просто реализовать IObservableCollection? ... |
|||
:
Нравится:
Не нравится:
|
|||
26.03.2012, 19:32 |
|
NHibernate Unit of Work и UI
|
|||
---|---|---|---|
#18+
CVlasovМожет, тогда подскажете как просто реализовать IObservableCollection? Если для NHIbernate - то подскажу . ... |
|||
:
Нравится:
Не нравится:
|
|||
27.03.2012, 09:18 |
|
NHibernate Unit of Work и UI
|
|||
---|---|---|---|
#18+
SolYUtor, не проще ли применить в данном случае, сессию без состояния. вытаскиваем листы на грид, связанные сущности грузим лениво сами из мутатора ( три года не работал с хибером) может он уже и научился лениво сам подгружать..( хотя на вряд ли) сохраняем персон и сущности в ручную о единице работы заботимся сами. Все под контролем, при исключении пользуемся той же сессией, там кеш запросов не забит, все чисто, и прозрачно. первый уровень кеша и нафиг не нужен на вьюху? ... |
|||
:
Нравится:
Не нравится:
|
|||
29.03.2012, 21:32 |
|
NHibernate Unit of Work и UI
|
|||
---|---|---|---|
#18+
пардон, вместо мутатора читать акцессор ... |
|||
:
Нравится:
Не нравится:
|
|||
29.03.2012, 21:48 |
|
NHibernate Unit of Work и UI
|
|||
---|---|---|---|
#18+
Где-то в степи, видите ли, открывать зонтик обычно удобно. Но кто в первый раз открыл его в кармане, на всю жизнь решит неудобно. Так и хибер при корявом использовании становится неудобным. Вот я не вижу никакой нужды рожать unit of work самому, когда за меня это делает хибер. Опять же непонятно, когда это было, чтобы хибер не умел лениво грузить сущности? Если сессия живёт относительно недолго, то кеш запросов и сущеностей будет в форме. Если вам всё это не нужно - то не берите хибер. Есть ведь Dapper , iBatis , BLToolkit , написать свой наконец, и в полной мере насладиться прелестями инфраструктурных задач. ... |
|||
:
Нравится:
Не нравится:
|
|||
29.03.2012, 22:11 |
|
NHibernate Unit of Work и UI
|
|||
---|---|---|---|
#18+
SolYUtor,ну на скоко помню ленивая подгруздка у сессий без состояния не работала, если сессия трудится только на на грид, то действительно нафиг плодить кеши первого уровня. ... |
|||
:
Нравится:
Не нравится:
|
|||
29.03.2012, 22:50 |
|
NHibernate Unit of Work и UI
|
|||
---|---|---|---|
#18+
Где-то в степиSolYUtor,ну на скоко помню ленивая подгруздка у сессий без состояния не работала, Ааа. Речь про Stateless. Так и есть. Но ленивая загрузка не проблема, если одним запросом загрузить всё, что надо. Где-то в степиесли сессия трудится только на на грид, то действительно нафиг плодить кеши первого уровня. на грид можно и проекции. Целые сущности там ни к чему. Хотя сессии без состояния можно и сущности грузить. ... |
|||
:
Нравится:
Не нравится:
|
|||
29.03.2012, 22:56 |
|
NHibernate Unit of Work и UI
|
|||
---|---|---|---|
#18+
SolYUtor, Вот подскажите такую фишку. Есть интерфейс IValidate, выкидываем в сущность проверку. А есть ли интерфейсы типа IChanged изменения объекта, ( искал не нашел) в прочем мжно пользоваться и IValidate, но не ко времени, желательно он бы срабатывал когда сущность проходит конвеер единицы работы, и исходил бы из кеша ( первый уровень аки Unit of Work) ... |
|||
:
Нравится:
Не нравится:
|
|||
29.03.2012, 23:06 |
|
NHibernate Unit of Work и UI
|
|||
---|---|---|---|
#18+
Я бы точно от него не оказался, в некоторых местах, тем более реализовать патчем не составит труда, а вот релизно было бы не плохо ( если нет) ... |
|||
:
Нравится:
Не нравится:
|
|||
29.03.2012, 23:09 |
|
NHibernate Unit of Work и UI
|
|||
---|---|---|---|
#18+
Где-то в степи, C IChanged есть некоторые сложности, и проблема тут не в NH. Сам хибер отслеживает изменения, но делает это специфически. Ему важны новая сущность, изменения в сохранённой сущности, удаление в сущености. Если вы хотите получать детализацию по изменениям, то количество вопросов становится гораздо большим. Скажем, есть новая сущность. Вот создали вы конструктором новую сущность. Что в ней изменилось? Возвращать все свойства? Ни одного? Спец. статус, что новая сущность? А если вы сохранили ее в сессии (т.е. синхронизировали состояние с бд), а потом еще раз изменили, что считать изменением? Ответы на многие из эти вопросы во много зависит от вашей задачи, как вы ведите изменения. А хиберу они интересны только в своём ключе сохранения. Как я решал такую задачу, если бы она у меня возникла? В общем, Castle.DynamicProxy + своя реализация хиберовской IProxyFactory (заодно это открывает дорогу к инъекции зависимостей из контейнера). Другие виды AOP'а, вроде PostSharp'а никто не отменял. ... |
|||
:
Нравится:
Не нравится:
|
|||
29.03.2012, 23:28 |
|
NHibernate Unit of Work и UI
|
|||
---|---|---|---|
#18+
SolYUtor, мне интересен был бы такой подход Person o; ............ session.Save(o)// выдала грязный объект ........... ............ session.Save(o) выдала грязный объект ..... ....... session.Flush(); ... |
|||
:
Нравится:
Не нравится:
|
|||
29.03.2012, 23:36 |
|
|
start [/forum/topic.php?fid=17&msg=37730480&tid=1350393]: |
0ms |
get settings: |
8ms |
get forum list: |
13ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
119ms |
get topic data: |
9ms |
get forum data: |
3ms |
get page messages: |
59ms |
get tp. blocked users: |
1ms |
others: | 340ms |
total: | 560ms |
0 / 0 |