如何跟踪在CRUD场景中从ObservableCollection中删除的对象?

Yan*_*ton 5 lifecycle entity-framework observablecollection self-tracking-entities

在我们的多层业务应用程序中,我们拥有ObservableCollections从服务调用返回的自我跟踪实体.

我们的想法是希望能够从集合客户端获取实体,添加,更新和删除它们,然后将这些更改发送到服务器端,并将它们保存到数据库中.

自我跟踪实体,正如其名称所暗示的那样,可以自己跟踪其状态.当创建一个新的STE时,它具有Added状态,当你修改一个属性时,它设置Modified状态,它也可以有Deleted状态,但是当从一个ObservableCollection(显然)中删除实体时,不会设置这个状态.如果您想要这种行为,您需要自己编写代码.

在我当前的实现中,当从中删除实体时ObservableCollection,我将其保存在阴影集合中,这样当ObservableCollection发送回服务器时,我可以发送已删除的项目,因此实体框架知道删除它们.

有点像:

protected IDictionary<int, IList> DeletedCollections = new Dictionary<int, IList>();

protected void SubscribeDeletionHandler<TEntity>(ObservableCollection<TEntity> collection)
{
    var deletedEntities = new List<TEntity>();
    DeletedCollections[collection.GetHashCode()] = deletedEntities;

    collection.CollectionChanged += (o, a) =>
        {
            if (a.OldItems != null)
            {
                deletedEntities.AddRange(a.OldItems.Cast<TEntity>());
            }
        };
}
Run Code Online (Sandbox Code Playgroud)

现在,如果用户决定将更改保存到服务器,我可以获取已删除项目的列表,并将其发送到:

ObservableCollection<Customer> customers = MyServiceProxy.GetCustomers();

customers.RemoveAt(0);

MyServiceProxy.UpdateCustomers(customers);
Run Code Online (Sandbox Code Playgroud)

此时,UpdateCustomers如果删除了任何项目,该方法将验证我的阴影收集,并将它们发送到服务器端.

这种方法很好,直到你开始考虑这些影子集合的生命周期.基本上,当ObservableCollection收集垃圾时,无法知道我们需要从字典中删除阴影集合.

我提出了一些复杂的解决方案,基本上在这种情况下进行手动内存管理.我保持WeakReferenceObservableCollection,并每隔几秒钟我检查,看看是否引用是无效的,在这种情况下,我删除了阴影集合.

但这似乎是一个可怕的解决方案......我希望StackOverflow的集体天才可以为更好的解决方案提供帮助.

编辑:

最后我决定继承子类化ObservableCollection.生成服务代理代码,因此更改它以返回我的派生类型是一个相对简单的任务.

感谢您的帮助!

Bin*_*ier 1

HttpRuntime.Cache您可以使用(可从所有项目类型获得,而不仅仅是 Web 项目),而不是滚动自己的“弱引用 + 轮询 Is it Dead、Is it Alive”逻辑。

将每个影子集合添加到缓存中,或者具有足够的超时时间,或者可以检查原始集合是否仍然存在的委托(或两者)。

它与您自己的解决方案并没有太大的不同,但它确实使用了经过考验且值得信赖的 .Net 组件。

除此之外,您正在考虑扩展 ObservableCollection 并使用该新类(我认为这是一个不小的变化),或者更改/包装UpdateCustomers方法以删除影子集合形式DeletedCollections

抱歉,我想不出其他的了,但希望这会有所帮助。
体重