Using dapper, why is a temp table created in one use of a connection not available in a second use of the same connection

前端 未结 3 1757
有刺的猬
有刺的猬 2021-01-17 18:32

I\'m trying to perform a series of SQL*Server steps using dapper from C#. One step creates a temp table and populates it. Following steps query data from the temp table.

相关标签:
3条回答
  • 2021-01-17 19:24

    I suspect the connection is not open. If so, dapper will open and close (back to the pool) the connection as needed. This will reset the connection, losing any temporary tables between commands.

    Just explicitly open the connection.

    0 讨论(0)
  • 2021-01-17 19:30

    I don't understand exactly what's going on, but I am able to work around the problem by creating the temp table in an Execute of its own, as opposed to in an Execute that both creates the table and populates it, as in the code shown in my question.

    That is, the following works:

                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>();
    

    This isn't horrible, but it is inconvenient. It's worth noting that I'd rather not have to explicitly create the temp table at all. Indeed, I'd originally coded the create/populate operation as a SELECT INTO so I didn't have to itemize the temp table's columns. But that also ran into the "invalid object" error on the subsequent query, so I tried the explicit CREATE TABLE to see if it made a difference and posted my question here after finding that it didn't.

    The behavior I'm seeing is that when the temp table is created and populated in the same Execute, it really isn't in tempdb after the Execute ends, ostensibly successfully. That leaves me to wonder if the Execute in my original code was doing anything at all! For all I can tell, it amounted to a NOOP.

    0 讨论(0)
  • 2021-01-17 19:32

    The following works perfectly for me:

    db.Open();
    db.Execute(
        @"create table #foo (val int not null);
          insert #foo (val) values (123)");
    db.Execute(
        @"insert #foo (val) values (456)");
    var vals = db.Query<int>(
        @"select * from #foo").ToList();
    foreach(var val in vals)
        Console.WriteLine(val);
    

    It also works perfectly if I use:

    @"select * from tempdb..#foo"
    

    The only way I can cause it to stop working is, as per my previous answer, to not open the connection first.

    0 讨论(0)
提交回复
热议问题