基于DataTable筛选另一DataTable时IN子句报错,求解决方案
问题原因与解决方案
你碰到的问题很典型——直接把List<int>对象拼进SQL字符串时,C#会默认调用它的ToString()方法,而这个方法返回的是对象的类型名称(也就是你看到的System.Collections.Generic.List1[System.Int32]`),不是列表里的实际数值。
快速修复:把列表转为逗号分隔的字符串
你需要先把SitNumList转换成逗号分隔的数字字符串,再拼进SQL语句里:
// 把List<int>转为"1,2,3,..."格式的字符串 string sitNumStr = string.Join(",", SitNumList); // 拼接SQL语句(注意:此方式存在SQL注入风险,仅作快速修复参考) DataTable dtPross = new DataTable(); using (SqlConnection conn = new SqlConnection("你的数据库连接字符串")) { string sql = $"select SitNum from dbo.Table2 where SitNum in ({sitNumStr})"; SqlDataAdapter adapter = new SqlDataAdapter(sql, conn); adapter.Fill(dtPross); }
更安全的方案:使用参数化查询(避免SQL注入)
直接拼接SQL字符串存在SQL注入风险,如果SitNumList里的内容来自用户输入,很容易被恶意利用。推荐用参数化查询来处理:
DataTable dtPross = new DataTable(); using (SqlConnection sqlConn = new SqlConnection("你的数据库连接字符串")) { sqlConn.Open(); // 为每个数值生成对应的参数占位符 string paramPlaceholders = string.Join(",", SitNumList.Select((_, index) => $"@SitNum{index}")); string sql = $"select SitNum from dbo.Table2 where SitNum in ({paramPlaceholders})"; using (SqlCommand cmd = new SqlCommand(sql, sqlConn)) { // 逐个添加参数,避免SQL注入 for (int i = 0; i < SitNumList.Count; i++) { cmd.Parameters.AddWithValue($"@SitNum{i}", SitNumList[i]); } // 加载数据到DataTable dtPross.Load(cmd.ExecuteReader()); } }
补充:原代码的小问题修正
你原来的代码里还有个语法错误:DataTable dtSeats = new DataTable();之后直接赋值dtSeats = "select SitNum,Num from dbo.Table1";是不对的,字符串不能直接赋值给DataTable,需要用数据库操作加载数据:
DataTable dtSeats = new DataTable(); using (SqlConnection sqlConn = new SqlConnection("你的数据库连接字符串")) { sqlConn.Open(); string sql = "select SitNum,Num from dbo.Table1"; using (SqlDataAdapter adapter = new SqlDataAdapter(sql, sqlConn)) { adapter.Fill(dtSeats); } } // 提取SitNum列表 List<int> SitNumList = dtSeats.AsEnumerable().Select(row => Convert.ToInt32(row["SitNum"])).ToList();
这样整个数据加载和筛选的流程就完整且安全了。
内容的提问来源于stack exchange,提问作者Abohy
相关产品推荐
相关产品推荐

