Dapper参数化查询字符串值导致问题?

时间:2016-06-13 16:57:27

标签: c# sql sql-server dapper

我在下面使用dapper进行参数化的方法#1查询,问题是即使在等待30秒后查询超时,通常在SSMS上使用普通sql最多需要1秒。

然而,方法#2查询实际上可以在服务器端而不是参数化查询的情况下构建查询。我注意到的一件事是,它可能与FirstName和LastName的过滤器有关,对于那些过滤器,我在方法#2上有单引号,但对于方法#1没有。

方法#1有什么问题?

Method # 1

string query = "SELECT *
                FROM dbo.Customer c                
                WHERE c.MainCustomerId = @CustomerId 
                AND (@IgnoreCustomerId = 1 OR c.CustomerID = @FilterCustomerId)
                AND (@IgnoreFirstName = 1 OR c.FirstName = @FilterFirstName)
                AND (@IgnoreLastName = 1 OR c.LastName = @FilterLastName)
                AND (@IgnoreMemberStatus = 1 OR c.CustomerStatusID = @FilterMemberStatus)
                AND (@IgnoreMemberType = 1 OR c.CustomerTypeID = @FilterMemberType)
                AND (@IgnoreRank = 1 OR c.RankID = @FilterRank)
                ORDER BY c.CustomerId
                OFFSET @OffSet ROWS
                FETCH NEXT 50 ROWS ONLY";       



                _procExecutor.ExecuteSqlAsync<Report>(query, new
            {
                CustomerId = customerId,
                IgnoreCustomerId = ignoreCustomerId,
                FilterCustomerId = filter.CustomerID,
                IgnoreFirstName = ignoreFirstName,
                FilterFirstName = filter.FirstName,
                IgnoreLastName = ignoreLastName,
                FilterLastName = filter.LastName,
                IgnoreMemberStatus = ignoreMemberStatus,
                FilterMemberStatus = Convert.ToInt32(filter.MemberStatus),
                IgnoreMemberType = ignoreMemberType,
                FilterMemberType = Convert.ToInt32(filter.MemberType),
                IgnoreRank = ignoreRank,
                FilterRank = Convert.ToInt32(filter.Rank),
                OffSet = (page - 1) * 50
            });


    Method # 2      

            string queryThatWorks =
                            "SELECT *
                 FROM dbo.Customer c                
                WHERE c.MainCustomerId = @CustomerId 
                AND ({1} = 1 OR c.CustomerID = {2})
                AND ({3} = 1 OR c.FirstName = '{4}')
                AND ({5}= 1 OR c.LastName = '{6}')
                AND ({7} = 1 OR c.CustomerStatusID = {8})
                AND ({9} = 1 OR c.CustomerTypeID = {10})
                AND ({11} = 1 OR c.RankID = {12})
                ORDER BY c.CustomerId
                OFFSET {13} ROWS
                FETCH NEXT 50 ROWS ONLY";

                _procExecutor.ExecuteSqlAsync<Report>(string.Format(queryThatWorks,
                customerId,
                ignoreCustomerId,
                filter.CustomerID,
                ignoreFirstName,
                filter.FirstName,
                ignoreLastName,
                filter.LastName,
                ignoreMemberStatus,
                 Convert.ToInt32(filter.MemberStatus),
                 ignoreMemberType,
                 Convert.ToInt32(filter.MemberType),
                 ignoreRank,
                  Convert.ToInt32(filter.Rank),
                 (page - 1) * 50
                ), null);

1 个答案:

答案 0 :(得分:5)

我以前无数次见过这个。

我愿意打赌您的专栏是varChar,但Dapper会将您的参数作为nVarChar发送。发生这种情况时,SQL Server必须对存储在每一行中的值运行转换。除了非常慢,这会阻止您使用索引。

请参阅https://github.com/StackExchange/dapper-dot-net

中的“Ansi字符串和varchar”