C# 实体框架-存储过程的执行时间非常长
我昨天正在跟进我的问题。我的存储过程现在在实体框架下运行。但是,它在3分钟后超时,连接超时 我在SQL Server Management Studio中使用以下行运行存储过程(省略客户信息): 它在不到一秒钟的时间内执行。当实体framwork执行它时,它将花费永远的时间 使用SQL Server探查器,我确定Entity Framework正在将此行发送到SQL Server:C# 实体框架-存储过程的执行时间非常长,c#,sql-server,entity-framework,stored-procedures,C#,Sql Server,Entity Framework,Stored Procedures,我昨天正在跟进我的问题。我的存储过程现在在实体框架下运行。但是,它在3分钟后超时,连接超时 我在SQL Server Management Studio中使用以下行运行存储过程(省略客户信息): 它在不到一秒钟的时间内执行。当实体framwork执行它时,它将花费永远的时间 使用SQL Server探查器,我确定Entity Framework正在将此行发送到SQL Server: exec sp_executesql N'EXEC spGetDupWOs',N'@ProjectName nva
exec sp_executesql N'EXEC spGetDupWOs',N'@ProjectName nvarchar(19),@City nvarchar(6),@State nvarchar(2),@ProjectNum nvarchar(12),@County nvarchar(10),@Owner nvarchar(23),@QuoteRecipients nvarchar(23),@ProjectID bigint',@ProjectName=N'...',@City=N'Holden',@State=N'LA',@ProposalNum=N'201703080740-001',@County=N'Livingston',@Owner=N'...',@BID_RECIP=N'...',@ProjectID=-1
当我在SSMS中运行它时,它需要永远运行
阅读类似的问题,问题似乎是参数嗅探和执行计划的变化
下面是我在应用程序中执行存储过程的调用:
List<DuplicateProposals> duplicateCheckResults =
db.Database.SqlQuery<DuplicateProposals>("spGetDupWOs",
spl.ToArray())
.ToList();
列出重复的检查结果=
SqlQuery(“spGetDupWOs”,
spl.ToArray())
.ToList();
在网上读了一大堆文章后,我更加困惑了。如何更改调用以解决此问题?确定的问题是SQL Server中的参数嗅探。有多种方法可以处理这个问题,但最适合您的场景取决于您的实际用例、利用率等 这里有一些选择
SELECT * FROM dbo.MyTable T
WHERE T.Col1 = @Param1 and T.Col2 = @Param2
OPTION(QUERYTRACEON 4136)
最后,我不得不将整个调用转换为一个字符串,并将其传递给SqlQuery函数
string sql = string.Format("exec spGetDupWOs @ProjectName=N'{0}',@City=N'{1}',@State=N'{2}',@ProjectNumber=N'{3}',@County=N'{4}',@Owner=N'{5}',@QuoteRecipients=N'{6}',@ProjectID={7}",
project.ProjectName,
project.City,
project.State,
project.ProjectNumber,
project.County,
project.Owner,
quoteRecipientsList,
"null");
是的,我必须在字符串中加入N前缀才能使它工作,我不知道为什么,但它工作了
谢谢大家的帮助。如果没有您的帮助,我无法解决此问题。您是否尝试过修复参数嗅探场景?仅此而已。我被我读到的东西弄糊涂了,我不知道怎么读。是否需要更改存储过程或应用程序调用?更改SP。例如:
CREATE PROC Thing(@param1 INT)为DECLARE@internal_param1 INT=@param1;从Column=@internal_param1
@DavidG的表中选择*:虽然这可以解决参数嗅探问题,但与单个麻烦语句的选项(优化…
或选项(重新编译)
相比,这是一种不直观的方法。本地复制参数应该是不必要的。@Jeroenmoster我不建议将这两种方法都作为参数嗅探的解决方案。我实现了第3种方法,几乎成功了。通过在SP中添加一些调试信息,我可以确定存储过程没有获得提供给它的参数。我最终将整个调用转换为字符串,并将其传递给SqlQuery函数。
string sql = string.Format("exec spGetDupWOs @ProjectName=N'{0}',@City=N'{1}',@State=N'{2}',@ProjectNumber=N'{3}',@County=N'{4}',@Owner=N'{5}',@QuoteRecipients=N'{6}',@ProjectID={7}",
project.ProjectName,
project.City,
project.State,
project.ProjectNumber,
project.County,
project.Owner,
quoteRecipientsList,
"null");