【问题标题】:How Do I Use CancellationTokenSource With DbContext.Database.SqlQuery<TElement>(Sp, Param)?如何将 CancellationTokenSource 与 DbContext.Database.SqlQuery<TElement>(Sp, Param) 一起使用?
【发布时间】:2018-02-20 17:49:55
【问题描述】:

如何将 CancellationTokenSource 与 DbContext.Database.SqlQuery(Sp, Param) 一起使用?

我正在使用 EF6.2 并运行具有返回类型的存储过程。

var task = Db.Database.SqlQuery<ResultType>(sp, params).ToListAsync();

foreach(var result in task.Result)
{
   var row = result;
}

我们当前的解决方案有取消令牌,但不返回任何内容:

var task = Db.Database.ExecuteSqlCommandAsync(sp, tokenSource.Token, param);

SqlQuery 只有一个方法签名,我在documentation 中看不到任何关于取消的内容

如何使用第一种方法并包含取消令牌? 编辑: 或者我应该使用其他方法吗?


附加信息: 我们当前的解决方案 ExecuteSqlCommandAsync() 返回一个任务,它的返回类型只有一个“已完成”的 int 状态。我正在调用的存储过程 只是一个 INSERT... 但我需要将其更改为 SELECT 以便我们可以生成带有结果的文件。

所以我需要一个返回“ResultType”类型任务的 EF 方法,这样我就可以遍历它们并生成我们的文件。

SqlQuery() 这样做...但无法添加取消令牌(无论如何,从它的外观来看,因此问题)

【问题讨论】:

  • “我们当前的解决方案有取消令牌,但不返回任何内容:” 好吧,这似乎是您的问题。您可能应该假设事实上,让您远离气味并不是开玩笑的方法。它确实返回东西。你没有正确使用它。您的第一步是在调用这两种方法时在运行时检查您的变量,以确保您不会把事情搞砸。下一步是使用 Sql Profiler 在访问数据库时检查这两个查询。有什么区别?为什么它们不同?
  • @如果不清楚,我很抱歉 - ExecuteSqlCommandAsync() 返回结果为 int 的任务(任务的完整状态为 int)。它用于 UPDATE 或 INSERT sps,而我要调用的 sp 是 SELECT。
  • @PeterBons 这不是最终代码,我更多的是表明我确实想要返回一个类型。我们将在实际代码中正确使用任务
  • 也许,也许不是……您可以使用 Profiler 对其进行测试,以查看刚刚获取的任务是否命中数据库。 EF 领域有很多魔法。总之,祝你好运。
  • 您必须将令牌传递给 .ToListAsync()。只有当 .ToListAsync(cancellationToken) 被调用时,查询才会具体化并发送到服务器。但请注意,传递取消令牌的选项可能不会产生您希望看到的效果,请参阅stackoverflow.com/questions/25387636/… TL;DR:查询仍将在 sql server 数据库级别运行完成。

标签: c# entity-framework-6


【解决方案1】:

您必须将令牌传递给.ToListAsync()。只有当.ToListAsync(cancellationToken) 被调用时,查询才会具体化并发送到服务器。

但请注意,传递 CancellationToken 的选项可能不会产生您希望看到的效果,请参阅 this Q&A/ TL;DR:查询仍将在 sql server 数据库级别运行完成。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-12
    • 2018-12-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多