使用RX订阅EF更改

时间:2013-07-04 20:10:17

标签: c# entity-framework system.reactive

我可能完全误解了RX的全部内容,但我认为在我的代码中允许各种客户端应用程序订阅某些Entity Framework Code First类型的更改通知将是一种巧妙的方式。

所以在我的UOW承诺中,我有

        var changes = DbContext.ChangeTracker.Entries<EntEvent>().Where(ee => ee.State != EntityState.Unchanged);
        Hub.Instance.NotifyBeforeSave(changes);

我的(相当基本的)集线器类看起来像这样......

public sealed class Hub
{
    private static readonly Hub instance = new Hub();
    static Hub(){}
    private Hub(){}
    public static Hub Instance
    {
        get { return instance; }
    }

    public IObservable<System.Data.Entity.Infrastructure.DbEntityEntry<EntEvent>> BeforeSave = new Subject<DbEntityEntry<EntEvent>>(); 
    public void NotifyBeforeSave<T>(IEnumerable<System.Data.Entity.Infrastructure.DbEntityEntry<T>> changes) where T:class
    {
        var  x = changes.Where(c => typeof(T) == typeof(EntEvent)) as IEnumerable<System.Data.Entity.Infrastructure.DbEntityEntry<EntEvent>>;
        BeforeSave = x.ToObservable();
    }
}

然后我想我可以通过创建以下的实例并调用attach来订阅客户端(观察者)。

public class SampleConsumer : IObserver<DbEntityEntry<EntEvent>>
{
    public void attach()
    {            
        Hub.Instance.BeforeSave.Subscribe(this);
    }

    public void OnNext(DbEntityEntry<EntEvent> value)
    {
        var x = value;
    }

    public void OnError(Exception error)
    {
        var y = error;
    }

    public void OnCompleted()
    {
    }
}

但OnNext和OnError中的断点永远不会被调用。

我可能距离我应该的地方180度,但我们必须从某个地方开始!

2 个答案:

答案 0 :(得分:1)

问题是你没有异步来源。

DbContext.ChangeTracker.Entries<EntEvent>()

是一个集合。您可以使用

将其转换为可观察对象
IEnumerble.ToObservable();

但这不会使它异步。事实上,它会在订阅后立即枚举收藏品。如果集合恰好是空的,它将什么都不做。谷歌冷/热可观测量之间的区别要理解。 您需要一个异步源,类似于事件。

我不太了解EF,我猜是

((IObjectContextAdapter)DbContext).ObjectContext.SavingChanges

事件可能就是您所需要的。

祝你好运!

答案 1 :(得分:0)

插上尼克的

https://github.com/NickStrupat/EntityFramework.Triggers https://github.com/NickStrupat/EntityFramework.Rx

他的模式有和没有来自他的背景,允许:

DbObservable<Context>.FromInserted<Person>();