C# Database.ExecuteSqlCommand()在执行存储过程时挂起

C# Database.ExecuteSqlCommand()在执行存储过程时挂起,c#,sql,entity-framework,asp.net-web-api,C#,Sql,Entity Framework,Asp.net Web Api,我正在使用一个我无法控制的数据库。我试图在C#Web API调用中使用Database.ExecuteSqlCommand方法执行存储过程。我已经能够在其他存储过程上成功地使用此方法,没有任何问题。但是,当我尝试执行这个特定的存储过程时,应用程序会冻结。我把它放在一个try-catch中,它不会抛出任何异常。它将无限期地停留在这种状态。我必须进入SSMS并终止与呼叫相关的进程。当我终止进程时,Web API将继续。如果我在SSMS中执行相同的EXEC命令,返回一个返回值为0的单行集合就可以了。我

我正在使用一个我无法控制的数据库。我试图在C#Web API调用中使用Database.ExecuteSqlCommand方法执行存储过程。我已经能够在其他存储过程上成功地使用此方法,没有任何问题。但是,当我尝试执行这个特定的存储过程时,应用程序会冻结。我把它放在一个try-catch中,它不会抛出任何异常。它将无限期地停留在这种状态。我必须进入SSMS并终止与呼叫相关的进程。当我终止进程时,Web API将继续。如果我在SSMS中执行相同的EXEC命令,返回一个返回值为0的单行集合就可以了。我在过程结束时手动添加了这个RETURN_VALUE=0,认为这可能是问题的一部分

C#代码是:

存储过程确实调用了一些其他存储过程以及一些插入、更新和删除。我知道其中一个嵌套存储过程也执行多个EXEC xp_cmdshell命令。我知道这并不是一个很大的问题,但我希望有人能帮助我找到一条至少能找到错误的途径。谢谢

编辑 我使用了SQL Server Profiler并找到了它的执行位置。我将集合复制/粘贴到SSMS查询窗口中,并且仍然能够成功地执行存储的过程

探查器窗口

SSMS查询


默认情况下,EF在事务中包装本机SQL命令调用。这可能是问题所在,具体取决于存储过程的功能。例如,如果存储过程进行链接服务器调用,这可能会导致它需要分布式事务

我怀疑这里发生的是事务导致了无法检测到的死锁,因为您的过程正在调用xp\u cmdshell。如果该外部程序试图读取存储过程写入的数据,则将其包装到事务中会导致该外部程序看不到您的更改,或阻止未提交的事务。(由于存储的进程正在使用xp_cmdshell间接创建第二个连接,因此SQL Server无法检测到死锁。)

无论如何,要禁用事务,请尝试:

entities.Configuration.EnsureTransactionsForFunctionsAndCommands = false;
entities.Database.ExecuteSqlCommand("EXEC [dbo].[SPCHANGEORDER]");

使用探查器从应用程序中捕获命令、用户和设置,您应该能够在SSMS中重新处理该问题。@DavidBrowne Microsoft我听从了您的建议,如果操作正确,即使使用了适用的设置,我也能够在SSMS中成功执行该过程。有关详细信息,请参见编辑。看起来不错。除了确保您使用与应用程序相同的登录名外,EF将在默认情况下将呼叫包装在事务中。因此,将其添加到SSMS复制中,或使用
dbContext.Configuration.EnsureTransactionsForFunctionsAndCommands=false关闭行为零碎点,也许;但是如果你的服务器出了问题,那应该是5xx的htt代码,而不是4xx的http代码;不要因为你的错误而责怪用户代理:)@MarcGravel我实际上从未得到结果代码,它根本不会出错或进展-/
entities.Configuration.EnsureTransactionsForFunctionsAndCommands = false;
entities.Database.ExecuteSqlCommand("EXEC [dbo].[SPCHANGEORDER]");