我有一个包含命令EXEC [sp_executesql]
的存储过程,并使用临时表#UserDetail
返回结果。
我遇到了通过LINQ2SQL或Entity Framework返回数据的问题。
我需要获取特定列并将此列映射到C#中的业务对象。
当我在Linq2SQL中创建DataContext时,我收到错误:
The return types for the following stored procedures could not be detected
并且在Entity Framework存储过程中返回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
答案 0 :(得分:1)
根本不需要动态SQL。您提到了每次都不重新编译查询的目标,但请考虑如何实现该目标:
因此,您需要将I / O和内存需求加倍,以节省一小部分CPU时间。您的存储过程似乎等同于:
CREATE PROC [SUPPORT].[GetUserDetail] @userId BIGINT
AS
BEGIN
SELECT u.UserId, u.UserName, u.Email
FROM dbo.[User] u
WHERE (@userId IS NULL OR u.UserId = @userId)
OPTION(RECOMPILE)
END
如果它能为您提供所需的结果,但似乎太慢,请在没有RECOMPILE
的情况下尝试,看看是否有帮助。我非常怀疑添加临时表和动态SQL只会通过保存偶尔的重新编译来提高性能。