Как справиться с созданием/редактированием сущности в master-detail

Мне интересно, какие стратегии люди используют для создания и редактирования объекта в настройке master-detail. (Наше приложение представляет собой настольное приложение с доступом в Интернет.)

Вот как мы сейчас справляемся с этим: во всплывающем окне создается форма для объекта, который необходимо отредактировать, которому мы даем копию объекта. Когда пользователь нажимает кнопку «Отмена», мы закрываем окно и полностью игнорируем объект. Когда пользователь нажимает кнопку «ОК», основное представление уведомляется и получает отредактированный объект. Затем он копирует свойства измененного объекта в исходный объект, используя originalEntity.copyFrom(modifiedEntity). Если мы хотим создать новый объект, мы передаем во всплывающее окно пустой объект, который затем пользователь может редактировать, как если бы это был существующий объект. Главное представление должно решить, следует ли «вставлять» или «обновлять» сущности, которые оно получает, в коллекцию, которой оно управляет.

У меня есть несколько вопросов и замечаний по описанному выше рабочему процессу:

  • кто должен заниматься созданием копии сущности? (мастер или деталь)
  • мы используем copyFrom(), чтобы предотвратить замену объектов в коллекции, что может привести к разрыву ссылок. Есть лучший способ сделать это? (реализация copyFrom() может быть сложной)
  • новые объекты получают идентификатор -1 (который используется уровнем сервера/спящим режимом, чтобы различать вставку или обновление). Это потенциально может вызвать проблемы при поиске (кэшированных) сущностей по идентификатору перед их сохранением. Должны ли мы вместо этого использовать временный уникальный идентификатор для каждой новой сущности?

Может ли кто-нибудь поделиться советами и рекомендациями или опытом? Спасибо!

Правка: я знаю, что на этот вопрос нет абсолютно неправильного или правильного ответа, поэтому я просто ищу людей, которые поделятся мыслями и плюсами и минусами того, как они справляются с основными/подробными ситуациями.


person Christophe Herreman    schedule 22.06.2009    source источник


Ответы (3)


Есть несколько способов изменить этот подход. Имейте в виду, что ни одно решение не может быть «неправильным» само по себе. Все зависит от деталей вашей ситуации. Вот один из способов освежевать кошку.

кто должен заниматься созданием копии сущности? (мастер или деталь)

Я вижу мастер как представление списка в памяти подмножества сохраняемых сущностей. Я бы позволил мастеру обрабатывать любые изменения в своем списке. Сам список может быть пользовательской коллекцией. Используйте событие ItemChanged, чтобы отправить мастеру уведомление о том, что элемент был обновлен и его необходимо сохранить. Запустите событие NewItem, чтобы уведомить мастер о вставке.

мы используем copyFrom(), чтобы предотвратить замену объектов в коллекции, что может привести к разрыву ссылок. Есть лучший способ сделать это? (реализация copyFrom() может быть сложной)

Вместо использования copyFrom() я бы передал существующую ссылку во всплывающее окно с подробностями. Если вы используете перечисляемую коллекцию для хранения основного списка, вы можете передать объект, возвращенный из list[index], в окно сведений. Сама ссылка будет изменена, поэтому нет необходимости использовать какой-либо метод замены в списке. Когда нажата кнопка OK, запустите это событие ItemChanged. Вы даже можете передать индекс, чтобы он знал, какой объект обновлять.

новые объекты получают идентификатор -1 (который используется уровнем сервера/спящим режимом, чтобы различать вставку или обновление). Это потенциально может вызвать проблемы при поиске (кэшированных) сущностей по идентификатору перед их сохранением. Должны ли мы вместо этого использовать временный уникальный идентификатор для каждой новой сущности?

Изменения не сохраняются сразу? Используйте Сеанс гибернации с шаблоном "Единица работы", чтобы определить, что вставляется и что обновляется. Есть и другие примеры Unit of Work. Возможно, вам придется просмотреть некоторые сообщения в блогах сообщества .NET, если на стороне Java не так много информации. В любом случае это одно и то же животное.

Надеюсь это поможет!

person Kevin Swiber    schedule 23.06.2009
comment
Спасибо за ваш отзыв. Проблема с передачей ссылок для редактирования заключается в том, что вы не можете просто отменить или отменить изменения без сохранения исходных значений объекта. - person Christophe Herreman; 25.06.2009
comment
Я думаю, что я мог что-то упустить. Для уточнения, вы говорите, что ваш основной список имеет разные состояния, например, грязный/чистый? Вы добавляете и редактируете элементы из мастера в окне сведений, нажимаете «ОК» в окне сведений, а затем должны фиксировать или откатывать изменения, используя какой-либо элемент управления в главном окне? - person Kevin Swiber; 25.06.2009
comment
Ваши объекты данных каким-то образом привязаны к форме, что не очевидно из вашего примера? Мне просто интересно, где вы вызываете свои методы .set. Думаю, я думаю в том же ключе, что и Кевин. - person Chris Ruffalo; 01.07.2009
comment
Мастер содержит кэшированный список постоянных объектов. Когда пользователь щелкает элемент из основного списка, открывается всплывающее окно с подробностями выбранного элемента, которые пользователь может редактировать. Мы используем копию выбранного элемента для редактирования, поэтому мы можем отменить изменения элемента, просто закрыв окно сведений. Однако, когда мы нажимаем «ОК» в деталях, мы закрываем всплывающее окно и должны объединить изменения. Изменения сохраняются не сразу. На мастере есть действие сохранения, которое сохраняет все изменения в базе данных через (асинхронные) удаленные вызовы. Здесь может быть интересен шаблон единицы работы. - person Christophe Herreman; 01.07.2009

Библиотека CSLA может сильно помочь в этой ситуации.

Однако, если вы хотите реализовать себя:

У вас есть главный объект, главный объект содержит список дочерних объектов.

Детальная форма может редактировать дочерний объект напрямую. Поскольку все является ссылочными типами, главный объект автоматически обновляется.

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

CSLA обрабатывает это с помощью свойства IsDirty(). В главном объекте вы должны запросить каждый дочерний объект, чтобы увидеть, не загрязнен ли он, и если да, то все сохранить (а также отслеживать, загрязнен ли сам главный объект)

Вы также можете справиться с этим через интерфейс INotifyPropertyChanged.

Что касается некоторых других ваших вопросов:

Вы хотите отделить свою логику. Сущность может обрабатывать хранение своих собственных свойств и правил целостности для себя, но логика того, как разные объекты взаимодействуют друг с другом, должна быть отдельной. Изучите шаблоны, такие как MVC или MVP.

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

Для идентификаторов использование GUID в качестве идентификатора может избавить вас от многих проблем, потому что тогда вам не нужно обращаться к базе данных, чтобы определить правильный идентификатор. Вы можете сохранить флаг на объекте, если он новый или нет (и, следовательно, должен быть вставлен или обновлен).

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

относительно отмены при отмене: в CSLA реализована отмена на n-уровне, но если вы пытаетесь сделать это вручную, я бы либо использовал вашу функцию CopyFrom, либо обновлял данные объекта из уровня сохраняемости при отмене (повторная выборка).

person Jason Coyne    schedule 02.07.2009

Я только что реализовал такую ​​модель. Но не используя NH, я использую свой собственный код для сохранения объектов в Oracle Db.

я использовал концепцию основной детали в той же веб-форме.

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

В режиме добавления сведений я просто заполняю пустой объект, идентификатор которого был сгенерирован в отрицательных числах статическим полем. И при нажатии кнопки «Сохранить сведения» я сохранил этот объект в списке сведений основной записи в сеансе Asp.NET.

При редактировании деталей просмотр я заполнил панель сведений выбранными деталями с помощью вызовов ajax с использованием Jquery и добавил это наказание чуть ниже строки, по которой щелкнули.

На кнопке «Сохранить» я сохранил основной сеанс (содержащий список деталей) в базе данных.

и я работал хорошо для меня, как будто мастеру нужно заполнить несколько деталей.

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

Надеюсь, это поможет :) Спасибо,

person Usama Khalil    schedule 19.01.2010