c# - 使用 dapper,为什么在一次使用连接时创建的临时表在第二次使用同一连接时不可用

标签 c# sql dapper temp-tables

我正在尝试使用 C# 中的 dapper 执行一系列 SQL*Server 步骤。第一步创建一个临时表并填充它。以下步骤从临时表查询数据。创建/填充似乎运行成功,但临时表中的第一个查询失败说:

"Invalid object name '#GetPageOfGlobalUsers'."

        using (SqlConnection connection = DBConnectionProvider.CreateConnection())
        {
            ... misc setup stuff...

            connection.Execute(@"
                create table #GetPageOfGlobalUsers(row int, EmailAddress nvarchar(max), LastName nvarchar(max), FirstName nvarchar(max), Id uniqueidentifier)
                insert into #GetPageOfGlobalUsers
                SELECT ROW_NUMBER() OVER (order by LastName, FirstName, EmailAddress) row,
                    EmailAddress, LastName, FirstName, Id 
                    FROM Users 
                    WHERE LastName like @search or FirstName like @search or EmailAddress like @search
            ", new { search = search }
            );

            int count = connection.Query<int>(@"
                SELECT count(*) from tempdb..#GetPageOfGlobalUsers
            ").Single<int>();

... more queries from the temp table follow

上面,执行有效,但查询失败,出现我上面提到的错误。 (请注意,无论我是否使用“tempdb..”前缀,我都会得到相同的错误。)带有两个哈希值的名称)一切正常。

我的理解是,以单个哈希命名的临时表受连接持续时间的影响,所以我不知道发生了什么。但我相信有人可以告诉我!

(顺便说一句,如果没有人告诉我“不要这样做”,除非根本无法完成,否则我将不胜感激。)

最佳答案

我不明白到底发生了什么,但我可以通过在它自己的执行中创建临时表来解决这个问题,而不是在既创建表又填充它的执行中,因为在我的问题中显示的代码中。

也就是下面的作品:

            connection.Execute(@"
                create table #PagesOfUsers(row int, 
                                           EmailAddress nvarchar(max), 
                                           LastName nvarchar(max), 
                                           FirstName nvarchar(max), 
                                           Id uniqueidentifier)"
                );

            connection.Execute(@"
                insert into #PagesOfUsers
                SELECT ROW_NUMBER() OVER (order by LastName, FirstName, EmailAddress) row,
                    EmailAddress, LastName, FirstName, Id 
                    FROM Users 
                    WHERE LastName like @search or FirstName like @search or EmailAddress like @search
            ", new { search = search }
            );

            int count = connection.Query<int>(@"
                SELECT count(*) from #PagesOfUsers
            ").Single<int>();

这并不可怕,但很不方便。值得注意的是,我根本不想显式创建临时表。实际上,我最初将创建/填充操作编码为 SELECT INTO,因此我不必逐项列出临时表的列。但这也在随后的查询中遇到了“无效对象”错误,所以我尝试了显式 CREATE TABLE 以查看它是否有所作为,并在发现它没有之后将我的问题发布在这里。

我看到的行为是,当在同一个执行中创建并填充临时表时,在执行结束后它实际上不在 tempdb 中,表面上是成功的。这让我想知道我的原始代码中的 Execute 是否在做任何事情!据我所知,它相当于一个 NOOP。

关于c# - 使用 dapper,为什么在一次使用连接时创建的临时表在第二次使用同一连接时不可用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21734905/

相关文章:

c# - 使用代码优先的外键分配

sql - 我可以在 SQL 中执行 max(count(*)) 吗?

sql - 使用查询结果设置下一个查询的表

mysql - 使用 MySQL 在字符串中查找语言(做子字符串?)

dapper - 有没有办法在 Dapper 中同时使用 MultiMapping 和 QueryMultiple?

c# - 将 LINQ to SQL 表映射到另一个非常相似的表,而无需迭代每个表

c# - 在 VS 2010 中扩展文件重命名

c# - .Net-通过Outlook发送的电子邮件应更新数据库

c# - 如何在sql中使用存储过程插入嵌套对象

c# - 我可以为 dapper-dot-net 映射指定数据库列名吗?