使用Dapper将param传递给SQL校验和函数

时间:2018-01-08 15:48:19

标签: c# .net-core dapper

面对奇怪的问题:

string sql = $@"SELECT * FROM SearchLogs
                            WHERE CHECKSUM(@query) = cs_SearchTerm 
                            AND Website = @website";          

 return await Connection.QueryFirstOrDefaultAsync<SearchLog>(sql,
                param: new { query, website });

记录100%存在于数据库中,但我得到nullcs_SearchTermcomputed, int, nullable字段。然后我试了一下:

DECLARE @term nvarchar(500)
SET @term = @query

SELECT * FROM SearchLogs
WHERE CHECKSUM(@term) = cs_SearchTerm AND Website = @website

但结果相同。然后我尝试分成两个操作:

 private async Task<int> SqlCheckSumAsync(string query)
 {
        string sql = @"SELECT CHECKSUM(@query)";

        return await Connection.ExecuteScalarAsync<int>(sql, param: new { query }, transaction: Transaction);
 }

string sql = $@"SELECT * FROM Search_Master 
                        WHERE cs_SearchTerm = @checksum
                        AND Website = @website";

        int checksum = await SqlCheckSumAsync(query);

        return (await Connection.QueryFirstOrDefaultAsync<Search_Master>(sql,
            param: new { checksum, website },
            transaction: Transaction));

但仍然没有得到积极的结果。我不知道我做错了什么?为什么我无法将参数传递给SQL scalar

1 个答案:

答案 0 :(得分:2)

从评论中可以看出:

 SELECT * FROM SearchLogs WHERE cs_SearchTerm = CHECKSUM('abc') AND Website = 'ICF'

所以:这告诉我你使用varchar输入计算了校验和。这非常重要,因为CHECKSUM('abc')提供了完全不同的答案,而不是CHECKSUM(N'abc')

select checksum('abc') as [Ansi], checksum(N'abc') as [Unicode]

给出:

Ansi        Unicode
----------- -----------
34400       1132495864

默认情况下,dapper使用nvarchar(因为.NET字符串是utf-16)。所以我们需要告诉dapper将其作为ANSI字符串传递;幸运的是,这很简单:

return await Connection.ExecuteScalarAsync<int>(sql,
    new { query = new DbString { Value = query, IsAnsi = true} },
    transaction: Transaction);

Dapper的DbString类型允许对字符串的发送方式进行细粒度控制,包括它们是unicode还是ANSI,以及它们是固定宽度(如果是这样:什么)或可变宽度。