RavenDB:异步 SaveChanges 会影响以后的更新吗?

发布于 2024-11-29 12:23:04 字数 1663 浏览 0 评论 0原文

作为学习 RavenDB 的一部分,我尝试根据每晚下载的列表更新股票集合。

我有一个 Stock 类,其中 Id 是股票代码:

public class Stock
{
    public string Id { get; set; }
    public StockStatus Status { get; set; }
}

我正在尝试使用此算法同步列表:

  1. 更新或插入现在下载的所有股票为“StillActive”。
  2. 上次状态为“活跃”的任何股票都意味着它们不在更新中,需要“删除”。
  3. 所有仍然“仍然活跃”的股票成为新的“活跃”股票。

下面是实现:

List<Stock> stocks = DownloadStocks();

using (var session = RavenContext.Store.OpenSession())
{
    foreach (Stock stock in stocks)
    {
        stock.Status = StockStatus.StillActive;
        session.Store(stock);
    }

    session.SaveChanges();

    session.PatchUpdateCutoffNow("Stocks/ByStatus", "Status:Active", "Status", StockStatus.Deleted);
    session.PatchUpdateCutoffNow("Stocks/ByStatus", "Status:StillActive", "Status", StockStatus.Active);
}

PatchUpdateCutoffNow 是一个扩展方法,它使用现在的截止值执行 UpdateByIndex:

public static void PatchUpdateCutoffNow(this IDocumentSession session, string indexName, string query, string name, object val)
{
    session.Advanced.DatabaseCommands.UpdateByIndex(indexName, 
        new IndexQuery() { Query = query, Cutoff = DateTime.Now },
        new[]
        {
            new PatchRequest
            {
                Type = PatchCommandType.Set,
                Name = name,
                Value = val.ToString()
            }
        });
}

我最终删除了很多不应该删除的股票。我的猜测是 SaveChanges 是异步的,并且在 PatchUpdateCutoffNow 启动时尚未完成,因此我最终得到了一些状态为“已删除”的股票,而它们应该是“活动”的。我猜想 IndexQuery 截止值不适用,因为 SaveChanges 并不直接针对“Stocks/ByStatus”索引。

有没有办法使 SaveChanges 同步或其他更适合 NoSQL/RavenDB 思维方式的方法?

As part of learning RavenDB, I am trying to update a collection of stocks based on a list I download nightly.

I have a Stock class where Id is the stock symbol:

public class Stock
{
    public string Id { get; set; }
    public StockStatus Status { get; set; }
}

I'm trying to sync the list with this algorithm:

  1. Update or insert all stocks downloaded now as "StillActive".
  2. Any stocks with the status of "Active" from last time means they weren't in the update and need to be "Deleted".
  3. All stocks still "StillActive" become the new "Active" stocks.

Here is the implementation:

List<Stock> stocks = DownloadStocks();

using (var session = RavenContext.Store.OpenSession())
{
    foreach (Stock stock in stocks)
    {
        stock.Status = StockStatus.StillActive;
        session.Store(stock);
    }

    session.SaveChanges();

    session.PatchUpdateCutoffNow("Stocks/ByStatus", "Status:Active", "Status", StockStatus.Deleted);
    session.PatchUpdateCutoffNow("Stocks/ByStatus", "Status:StillActive", "Status", StockStatus.Active);
}

PatchUpdateCutoffNow is an extension method that does an UpdateByIndex with a Cutoff of now:

public static void PatchUpdateCutoffNow(this IDocumentSession session, string indexName, string query, string name, object val)
{
    session.Advanced.DatabaseCommands.UpdateByIndex(indexName, 
        new IndexQuery() { Query = query, Cutoff = DateTime.Now },
        new[]
        {
            new PatchRequest
            {
                Type = PatchCommandType.Set,
                Name = name,
                Value = val.ToString()
            }
        });
}

I end up with a lot of stocks Deleted that shouldn't be. My guess is the SaveChanges is asynchronous and doesn't finish by the time the PatchUpdateCutoffNow starts so I end up with some amount of Stocks with a status of "Deleted" when they should be "Active". I guess the IndexQuery cutoff doesn't apply since the SaveChanges isn't directly against the "Stocks/ByStatus" index.

Is there a way to make SaveChanges synchronous or some other way to do this that fits more with the NoSQL/RavenDB way of thinking?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

旧故 2024-12-06 12:23:04

文档会立即存储,但修补命令适用于尚未更新的索引。也许这会有所帮助,插入到 SaveChanges() 和修补之间:

using (var s = RavenContext.Store.OpenSession()) {
    s
        .Query<Stock>("Stocks/ByStatus")
        .Customize(c => c.WaitForNonStaleResultsAsOfNow())
        .Take(0)
        .ToArray();
}

顺便说一句,您不需要 DatabaseCommands 会话,您可以直接在商店上调用它们。

The documents are stored right away, but the patch commands work on an index which has not updated yet. Maybe this helps, inserted between SaveChanges() and the patching:

using (var s = RavenContext.Store.OpenSession()) {
    s
        .Query<Stock>("Stocks/ByStatus")
        .Customize(c => c.WaitForNonStaleResultsAsOfNow())
        .Take(0)
        .ToArray();
}

By the way, you don't need a session for DatabaseCommands, you can call them directly on the store.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文