有数组查询条件比如Ids=int?[]{1,2,3,4},这样再拼接SQL语句的时候写成id=@Ids,

SqlParameters.Add(new SqlParameter("@Ids",Ids)),代码层面是没错,但是查询数据库时会报错。

{"不存在从对象类型 System.Nullable`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]][] 到已知的托管提供程序本机类型的映射。"}

找了很多解决方法,个人觉得比较好的是【为每一个参数生成一个参数实现where in 参数化】

可以循环一下数组,然后sql语句拼接成id in (@Ids1,@Ids2,@Ids3,@Ids4),然后参数也是多个,

SqlParameters.Add(new SqlParameter("@Ids1",1));

SqlParameters.Add(new SqlParameter("@Ids2",2));

SqlParameters.Add(new SqlParameter("@Ids3",3));

SqlParameters.Add(new SqlParameter("@Ids4",4));

这样就解决了。

网上还看到一种用临时表的解决方法,由于需要创建临时表,会带来额外的IO开销,若查询频率很高,参数不多的话建议使用上面的方法,如果参数很多可以使用临时表的方法性能很好,方法如下:

using (SqlConnection conn = new SqlConnection(connectionString))

{

    conn.Open();

    SqlCommand comm = new SqlCommand();

    comm.Connection = conn;

    string sql = @"

        declare @Temp_Variable varchar(max)

        create table #Temp_Table(Item varchar(max))

        while(LEN(@Temp_Array) > 0)

        begin

            if(CHARINDEX(',',@Temp_Array) = 0)

            begin

                set @Temp_Variable = @Temp_Array

                set @Temp_Array = ''

            end

            else

            begin

                set @Temp_Variable = LEFT(@Temp_Array,CHARINDEX(',',@Temp_Array)-1)

                set @Temp_Array = RIGHT(@Temp_Array,LEN(@Temp_Array)-LEN(@Temp_Variable)-1)

            end    

        insert into #Temp_Table(Item) values(@Temp_Variable)

        end    

        select * from Users(nolock) where exists(select 1 from #Temp_Table(nolock) where #Temp_Table.Item=Users.UserID)

        drop table #Temp_Table";

    comm.CommandText = sql;

    comm.Parameters.Add(new SqlParameter("@Temp_Array", SqlDbType.VarChar, -1) { Value = "1,2,3,4" });

    comm.ExecuteNonQuery();

}