Обработка транзакций и исключений из базы данных в TreeView с многоуровневым MVVM - PullRequest
2 голосов
/ 27 июля 2010

Справочная информация:
У меня есть пользовательский элемент управления, основанный на WPF TreeView. Я использовал шаблон MVVM и имею базовую модель вида TreeNode и несколько производных моделей вида, таких как LocationNode, LocationFolder, PersonNode, PersonFolder, CollectionNode, CollectionFolder, etc..

Пример того, как можно выложить дерево:


- CollectionFolder
--> CollectionNode
    --> LocationFolder
        -->LocationNode
        -->LocationNode
    --> PersonFolder
        -->PersonNode
--> CollectionNode
--> CollectionNode
+ CollectionFolder
+ CollectionFolder   

Когда я выполняю операции перетаскивания, каждый класс обрабатывает бизнес-логику, т. Е. Если я перетаскиваю на PersonNode на CollectionNode, модель представления CollectionNode содержит логику, как добавить PersonNode это его ребенок PersonFolder.

Проблема:
Все отлично работает, я могу перетаскивать их повсюду, и код прекрасно содержится в классах dervied. Если мне нужно добавить дополнительное правило удаления, я добавляю его в соответствующую модель представления цели удаления.

Проблема заключается в том, что PersonNode добавляется к PersonFolder. Мне нужно создать новую запись в базе данных, чтобы отразить, что базовая модель Person теперь включена и в новую Collection.

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

Фрагмент кода из моего Drop события в моем PersonFolder


// Create a new view model for the Person and add it to my children
_children.Add( new PersonNode( droppedPerson ) );

// Create a new entry in the collection for this person
CollectionEntry entry = new CollectionEntry();
entry.Entity = droppedPerson;
entry.Collection = _collection;

// Save the new entry
using( var transaction = _uow.BeginTransaction( IsolationLevel.Serializable ) )
{
    // Add the entry to the session
    _uow.Add( entry );

    // Save the session
    _uow.SaveChanges(); // [1]

    // Commit transaction
    transaction.Commit(); // [2]
}

[1] и [2] могут генерировать исключения и должны обрабатываться в инструкциях try / catch. Тем не менее, я не хочу дублировать всю мою обработку исключений во всех моделях представления, какие-либо предложения?

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

1 Ответ

1 голос
/ 29 июля 2010

Я предполагаю, что переменная часть вашего последнего блока кода:

_uow.Add( entry );

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

Я думаю, что это хороший кандидат на " Отверстие в среднем паттерне ".

В основном просто передать

Action<T>

в другое место (Singleton, что угодно), которое открывает транзакцию, передает контекст (_uow) вашему действию, а затем фиксирует транзакцию и обрабатывает всю логику исключений. Ваш код будет выглядеть так:


// Create a new view model for the Person and add it to my children
_children.Add( new PersonNode( droppedPerson ) );

// Create a new entry in the collection for this person
CollectionEntry entry = new CollectionEntry();
entry.Entity = droppedPerson;
entry.Collection = _collection;

someSingleton.Execute(o => o.Add(entry));

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