当我有参数时,Dapper调用sp_executesql,有没有办法解决这个问题?

时间:2014-01-21 18:13:32

标签: dapper

当我打电话

connection.Execute(sql);

Dapper执行,一切都很好。当我打电话

connection.Execute(sql, new { UserId = _userId });

它使用sp_executesql执行。

问题是当它使用sp_executesql时,它在自己的范围内。如果它创建临时表,则使用相同连接的后续查询无法访问它。我可以通过使用全局临时表来绕过它,但我不想冒两个进程相互干扰的风险。

有人知道解决方法吗?

更新:我在没有Dapper的情况下使用SqlCommand对象时遇到同样的问题。我写了一个单元测试来说明我遇到的问题。 WorksWithParameters因System.Data.SqlClient.SqlException而失败:无效的对象名称'#TEMP_OBJECTLIST'。

[TestFixture]
public class DapperTest
{
    private const string TestObjectType = "S";
    private const string ConnectionString = "XXXXXXXXX";

    private static void CreateTempTableWithoutParameters(SqlConnection connection)
    {
        const string sql = "SELECT TOP 10 * INTO #TEMP_OBJECTLIST FROM sys.objects WHERE TYPE = 'S'";
        connection.Execute(sql);
    }

    private static void UseTempTableWithoutParameters(SqlConnection connection)
    {
        const int expectedCount = 10;

        const string sql = "SELECT COUNT(*) FROM #TEMP_OBJECTLIST WHERE TYPE = 'S'";
        var count = connection.Query<int>(sql).First();

        Assert.AreEqual(expectedCount, count);
    }

    private static void CreateTempTableWithParameters(SqlConnection connection)
    {
        const string sql = "SELECT TOP 10 * INTO #TEMP_OBJECTLIST FROM sys.objects WHERE TYPE = @OBJECT_TYPE";
        connection.Execute(sql, new {OBJECT_TYPE = TestObjectType});
    }

    private static void UseTempTableWithParameters(SqlConnection connection)
    {
        const int expectedCount = 10;

        const string sql = "SELECT COUNT(*) FROM #TEMP_OBJECTLIST WHERE TYPE = @OBJECT_TYPE";
        var param = new {OBJECT_TYPE = TestObjectType};

        var count = connection.Query<int>(sql, param).First();

        Assert.AreEqual(expectedCount, count);
    }

    [Test]
    public void WorksWithParameters()
    {
        using (var connection = new SqlConnection(ConnectionString))
        {
            connection.Open();

            CreateTempTableWithParameters(connection);
            UseTempTableWithParameters(connection);
        }
    }

    [Test]
    public void WorksWithoutParameters()
    {
        using (var connection = new SqlConnection(ConnectionString))
        {
            connection.Open();

            CreateTempTableWithoutParameters(connection);
            UseTempTableWithoutParameters(connection);
        }
    }
}

1 个答案:

答案 0 :(得分:0)

临时表范围问题的一种方法是在外部作用域中创建一个带有一个虚拟列的临时表,然后使用alter table语句添加所有需要的列并使用它。

此外,Erland Sommarskog的How to share data between procedures可能对您或寻找不同共享数据选项的其他人有用。