如何在Observable链中重用对象实例?

时间:2018-04-25 02:36:36

标签: system.reactive

在rx中,您如何处理在下一步中重复使用对象实例的需求?例如,我需要在ORM中获取上下文然后进行操作。 Async / Await的语法如下:

    public async Task<IList<string>> Delete(IList<string> ids)
    {
        var context = await _contextFactory.CreateContext();
        context.Set<T>().RemoveRange(
            context.Set<T>().Where(item => ids.Contains(item.Id)));
        return ids;
    }

Observable版本

    public IObservable<string> DeleteObservable(IList<string> ids)
    {
        return ids.ToObservable()
            .Select(i =>
            {
                var context = await _contextFactory.CreateContext();
                context.Set<T>().RemoveRange(
                    context.Set<T>().Where(item => item.Id == id));
                return id;
            });
    }

但是,每次删除项目时,我都不想创建新的上下文。我想创建一个上下文,然后在select中重用它。我该怎么做?

是的,在这个例子中,最好还缓冲并一起提交ID,但这只是我的问题的一个例子。我希望这部分不会分散注意力。

2 个答案:

答案 0 :(得分:3)

更惯用的做法是:

public IObservable<string> DeleteObservable(IList<string> ids)
{
    return Observable.Using(
        async () => await _contextFactory.CreateContext(),
        context =>
            ids.ToObservable().Select(i =>
            {
                context.Set<T>().RemoveRange(context.Set<T>().Where(item => item.Id == i));
                return i;
            }));
}

Observable.Using方法创建一个可处置资源,当对observable的订阅关闭时,该资源会被释放。

唯一的问题是语句context.Set<T>().RemoveRange(context.Set<T>().Where(item => item.Id == i));不应该在这样的可观察范围内。 Rx是关于查询的。任何更改都应使用。Subscribe方法。

你想要达到什么目标?

答案 1 :(得分:-1)

我认为我得到了它并且答案最终成为了&#39; SelectMany&#39;。我想我还是习惯了这些操作员。

    public IObservable<string> DeleteObservable(IList<string> ids)
    {
        return Observable
                .Return(_contextFactory)
                .SelectMany(factory => factory.CreateContext())
                .Zip(ids.ToObservable(), (dbContext, entityId) =>
        {
            dbContext.Set<T>().RemoveRange(
                dbContext.Set<T>().Where(item => item.Id == entityId));
            return entityId;
        });
    }