处理数据库事务&具有多层MVVM的TreeView中的异常

时间:2010-07-27 12:58:54

标签: c# wpf mvvm exception-handling treeview

背景
我有一个基于WPF TreeView的自定义用户控件。我一直在使用MVVM模式,并有一个基本视图模型TreeNode类和几个派生视图模型,如LocationNode, LocationFolder, PersonNode, PersonFolder, CollectionNode, CollectionFolder, etc..

如何布置树的示例是:


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

当我执行拖放操作时,每个类处理业务逻辑,即如果我放在PersonNode上的CollectionNodeCollectionNode视图模型包含逻辑如何开启要将PersonNode添加到其子PersonFolder

问题:
一切都很好,我可以拖放到整个地方,代码很好地包含在dervied类中。如果我需要添加额外的删除规则,我将其添加到适当的放置目标视图模型。

问题是当PersonNode添加到PersonFolder时,我需要创建一个新的数据库条目,以反映基础Person模型现在也在新的Collection中1}}。

目前,树中的每个视图模型都可以访问当前数据库会话/事务,并且可以执行插入/保存。但这使得捕获异常和错误非常重复,我的异常处理代码在我的视图模型中被复制。 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 个答案:

答案 0 :(得分:1)

我假设你最后一个代码块的变量部分是:

_uow.Add( entry );

...因此,在某些情况下,您可能实际上希望在该位置发生更多或更少的操作。

我认为这是“Hole in the Middle Pattern”的好候选人。

基本上只是传递

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));