如何将具有sp_executesql的特定表列返回到LINQ2SQL或实体框架?

时间:2015-10-12 14:37:56

标签: c# sql-server entity-framework stored-procedures

我有一个包含命令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

1 个答案:

答案 0 :(得分:1)

根本不需要动态SQL。您提到了每次都不重新编译查询的目标,但请考虑如何实现该目标:

  • 创建临时表
  • 创建动态SQL语句(重新编译,如果&#34;必要&#34;)
  • 填写临时表
  • 从临时表中选择所有数据

因此,您需要将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只会通过保存偶尔的重新编译来提高性能。