【发布时间】:2015-10-12 14:37:56
【问题描述】:
我有一个包含命令EXEC [sp_executesql] 的存储过程,并使用临时表#UserDetail 返回结果。
我在通过 LINQ2SQL 或实体框架返回数据时遇到问题。
我需要获取特定列并将这些列映射到我在 C# 中的业务对象。
当我在 Linq2SQL 中创建 DataContext 时出现错误:
The return types for the following stored procedures could not be detected
并且在实体框架存储过程中返回 int 不是特定的列。
如何修改这个存储过程来做到这一点?
CREATE PROC [SUPPORT].[GetUserDetail] @userId BIGINT
AS
BEGIN
CREATE TABLE #UserDetail
(
[UserId] BIGINT NOT NULL,
[UserName] VARCHAR(50) NOT NULL,
[Email] VARCHAR(150) NOT NULL
)
DECLARE @ExecStr NVARCHAR(4000) ,
@Recompile BIT = 0;
SELECT @ExecStr = 'INSERT INTO #UserDetail
( UserId, UserName, Email
)';
SELECT @ExecStr = @ExecStr
+ N'SELECT u.UserId, u.UserName, u.Email FROM dbo.[User] u WHERE 1=1';
IF @userId IS NOT NULL
OR @userId <> ''
SELECT @ExecStr = @ExecStr + N' AND (u.UserId = @userId)';
IF @userId IS NULL
BEGIN
SET @Recompile = 1
END
IF @Recompile = 1
BEGIN
SELECT @ExecStr = @ExecStr + N' OPTION(RECOMPILE)';
END
EXEC [sp_executesql] @ExecStr, N'@userId BIGINT', @userId = @userId;
SELECT ud.UserId, ud.UserName, ud.Email
FROM #UserDetail ud
END
【问题讨论】:
-
为什么需要动态SQL?问题是编译器无法确定从存储过程返回的列将是什么。
-
@DStanley 我需要通过 (OPTION(RECOMPILE)) sql 查询重新编译 where 条件下的特定过滤器。
-
为什么?您遇到过哪些具体问题让您认为需要强制重新编译?听起来您正试图通过智取编译器来解决性能问题。
-
或者为什么不每次都重新编译?编译这样一个简单的查询应该不会产生很大的开销。
-
@DStanley 是的,我想解决性能问题。当我插入 UserId 时,我只得到一条记录,我不需要重新编译和重新创建执行计划,但是当我没有搜索条件时,我需要新的执行计划。
标签: c# sql-server entity-framework stored-procedures