【发布时间】: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