Asp.net 将varchar转换为int:SQL数据类型时,转换失败

Asp.net 将varchar转换为int:SQL数据类型时,转换失败,asp.net,sql-server,dapper,dynamicparameters,Asp.net,Sql Server,Dapper,Dynamicparameters,我正在asp.net mvc中创建一个web应用程序。我有一个如下所示的查询 using (SqlConnection conn = new SqlConnection(_connStr)) { conn.Open(); var p = new DynamicParameters(); p.Add("@SP_RoleId", "7,8,9", dbType: DbType.String, direction: ParameterDirection.Input);

我正在asp.net mvc中创建一个web应用程序。我有一个如下所示的查询

using (SqlConnection conn = new SqlConnection(_connStr))
{
    conn.Open();

    var p = new DynamicParameters();
    p.Add("@SP_RoleId", "7,8,9", dbType: DbType.String, direction: ParameterDirection.Input);
    p.Add("@SP_UserId", userId, dbType: DbType.Int32, direction: ParameterDirection.Input);

    var obj = conn.Query<PendingKmsRequest>(sql: "SELECT [f].[id] AS [FileId],[fvr].[Id] AS [RequestId], [au].[Name]"
                        + ", [fvr].[RequestByUserId], [fvr].[FromDate], [fvr].[ToDate],[f].[Title], [fvr].[Status], [fvr].[StatusRemarks]"
                        + "FROM [dbo].[File] AS[f]"
                        + "INNER JOIN [dbo].[FileViewRequest] AS [fvr] ON [f].[CurrentFileVersionId] = [fvr].[FileVersionId]"
                        + "INNER JOIN [Access].[User] AS [au] ON [fvr].[RequestByUserId] = [au].[Id]"
                        + "WHERE ([fvr].[Status] = 'P' OR ([fvr].[Status] = 'A' AND [fvr].[StatusByUserId] = @SP_UserId AND GETDATE() BETWEEN [fvr].[FromDate] AND [fvr].[ToDate]))"
                        + "AND (SELECT 1 FROM [Access].[UserRoleMap] WHERE UserId=@SP_UserId AND RoleId IN(@SP_RoleId)) = 1", param: p, commandType: CommandType.Text);

    if (obj != null && obj.Count() > 0)
        return obj.ToList();
    else
        return new List<PendingKmsRequest>();
}
这就是错误:

将nvarchar值“7,9,10”转换为数据类型int时,转换失败


如何防止此错误?

问题代码中的以下行:

p.Add("@SP_RoleId", "7,8,9", dbType: DbType.String, direction: ParameterDirection.Input);
“7,8,9”
是字符串,参数类型
DbType.string
也是字符串

但是,您说过这是数据库中的
int
。这是不匹配的

此外,您的查询:

WHERE UserId = @SP_UserId AND RoleId IN (@SP_RoleId))
查询正在使用子句中的

如果传入一个
IEnumerable
,Dapper可以转换
子句中
的值

更改代码行,如下所示:

p.Add("@SP_RoleId", new[] {7,8,9}, dbType: DbType.Int32, direction: ParameterDirection.Input);

无需在
数组中使用convert string
或任何字符串
split()
函数

如果您有逗号字符串,那么您可以按照以下步骤进行检查

  • 如果您有
    @SP_RoleId=“7,8,9”
  • 您可以按如下方式转换此字符串
    @SP_RoleId=“,7,8,9,”
    ”,“+ltrim(rtrim)(@SP_RoleId))+”,“
  • 现在使用
    一样检查
    ,UserId,
  • 更新代码如下所示

    using (SqlConnection conn = new SqlConnection(_connStr))
    {
        conn.Open();
    
        var p = new DynamicParameters();
        p.Add("@SP_RoleId", "7,8,9", dbType: DbType.String, direction: ParameterDirection.Input);
        p.Add("@SP_UserId", userId, dbType: DbType.Int32, direction: ParameterDirection.Input);
    
        var obj = conn.Query<PendingKmsRequest>(sql: "SELECT [f].[id] AS [FileId],[fvr].[Id] AS [RequestId], [au].[Name]"
                            + ", [fvr].[RequestByUserId], [fvr].[FromDate], [fvr].[ToDate],[f].[Title], [fvr].[Status], [fvr].[StatusRemarks]"
                            + "FROM [dbo].[File] AS[f]"
                            + "INNER JOIN [dbo].[FileViewRequest] AS [fvr] ON [f].[CurrentFileVersionId] = [fvr].[FileVersionId]"
                            + "INNER JOIN [Access].[User] AS [au] ON [fvr].[RequestByUserId] = [au].[Id]"
                            + "WHERE ([fvr].[Status] = 'P' OR ([fvr].[Status] = 'A' AND [fvr].[StatusByUserId] = @SP_UserId AND GETDATE() BETWEEN [fvr].[FromDate] AND [fvr].[ToDate]))"
                            + "AND (SELECT 1 FROM [Access].[UserRoleMap] WHERE ',' +  lTrim(rTrim(@SP_RoleId)) + ',' like '%,' + lTrim(rTrim(UserId) + ',%' " // Updated line
                            + "AND RoleId IN(@SP_RoleId)) = 1", param: p, commandType: CommandType.Text);
    
        if (obj != null && obj.Count() > 0)
            return obj.ToList();
        else
            return new List<PendingKmsRequest>();
    }
    
    使用(SqlConnection-conn=newsqlconnection(_-connStr))
    {
    conn.Open();
    var p=新的动态参数();
    p、 添加(“@SP_RoleId”,“7,8,9”,dbType:dbType.String,direction:ParameterDirection.Input);
    p、 添加(“@SP_UserId”,UserId,dbType:dbType.Int32,direction:ParameterDirection.Input);
    var obj=conn.Query(sql:“选择[f].[id]作为[FileId],[fvr].[id]作为[RequestId],[au].[Name]”
    +“,[fvr].[RequestByUserId],[fvr].[FromDate],[fvr].[ToDate],[f].[Title],[fvr].[Status],[fvr].[Status备注]”
    +“从[dbo].[File]作为[f]”
    +“将[dbo].[FileViewRequest]作为[f].[CurrentFileVersionId]=[fvr].[FileVersionId]上的[fvr]进行内部联接”
    +“在[fvr].[RequestByUserId]=[au].[Id]上以[au]身份将[Access].[User]作为内部联接”
    +“其中([fvr].[Status]='P'或([fvr].[Status]='A'和[fvr].[StatusByUserId]=@SP_UserId和GETDATE(),介于[fvr].[FromDate]和[fvr].[ToDate])”
    +“和(从[Access].[UserRoleMap]中选择1,其中','+lTrim(rTrim(@SP_RoleId))+','类似','+lTrim(rTrim(UserId)+',%'”//更新行
    +“AND RoleId IN(@SP_RoleId))=1”,参数:p,commandType:commandType.Text);
    如果(obj!=null&&obj.Count()>0)
    返回obj.ToList();
    其他的
    返回新列表();
    }
    
    列中的RoleID是一个int,但是当您的条件包含逗号“,”时,您的条件是一个字符串,而不是int。请查看解决方案,您使用的是哪个版本的SQL server?SQL server 2008,如果您有
    “7,8,9”,则我不能使用字符串分割
    @SP_RoleId
    中作为字符串,因此无需在数组中转换它。您可以在字符串的开头和结尾添加逗号,并使用
    一样检查
    、用户ID、
    ltrim()
    rtrim()
    来删除额外的字符串spaces@IbrahimShaikh,答案更新为描述
    using (SqlConnection conn = new SqlConnection(_connStr))
    {
        conn.Open();
    
        var p = new DynamicParameters();
        p.Add("@SP_RoleId", "7,8,9", dbType: DbType.String, direction: ParameterDirection.Input);
        p.Add("@SP_UserId", userId, dbType: DbType.Int32, direction: ParameterDirection.Input);
    
        var obj = conn.Query<PendingKmsRequest>(sql: "SELECT [f].[id] AS [FileId],[fvr].[Id] AS [RequestId], [au].[Name]"
                            + ", [fvr].[RequestByUserId], [fvr].[FromDate], [fvr].[ToDate],[f].[Title], [fvr].[Status], [fvr].[StatusRemarks]"
                            + "FROM [dbo].[File] AS[f]"
                            + "INNER JOIN [dbo].[FileViewRequest] AS [fvr] ON [f].[CurrentFileVersionId] = [fvr].[FileVersionId]"
                            + "INNER JOIN [Access].[User] AS [au] ON [fvr].[RequestByUserId] = [au].[Id]"
                            + "WHERE ([fvr].[Status] = 'P' OR ([fvr].[Status] = 'A' AND [fvr].[StatusByUserId] = @SP_UserId AND GETDATE() BETWEEN [fvr].[FromDate] AND [fvr].[ToDate]))"
                            + "AND (SELECT 1 FROM [Access].[UserRoleMap] WHERE ',' +  lTrim(rTrim(@SP_RoleId)) + ',' like '%,' + lTrim(rTrim(UserId) + ',%' " // Updated line
                            + "AND RoleId IN(@SP_RoleId)) = 1", param: p, commandType: CommandType.Text);
    
        if (obj != null && obj.Count() > 0)
            return obj.ToList();
        else
            return new List<PendingKmsRequest>();
    }