You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Dapper将大型整数列表插入SQL Server表变量?

解决Dapper插入整数列表到SQL Server表变量的问题

一、语法错误的原因及解决方案

你的代码触发语法错误,核心原因是SQL Server的VALUES子句无法直接识别Dapper传入的列表参数@Ids——SQL Server会把它当作单个标量值而非集合处理。结合你提到的列表元素可能超过1000个的场景,推荐使用**表值参数(TVP)**来处理,这是SQL Server应对大量数据集合最高效的方案,且没有1000条的行数限制。

步骤1:创建SQL Server表值类型(仅需执行一次)

首先在SQL Server中创建匹配的表值类型:

CREATE TYPE IntList AS TABLE (Id INT);

步骤2:修改Dapper代码适配TVP

调整SQL语句与C#代码,用表值参数传递列表:

List<int> output = null; 
List<int> input = new List<int> { 1, 2, 3, ... }; // 支持超过1000个元素

// 将List<int>转换为适配表值参数的DataTable
var dataTable = new DataTable();
dataTable.Columns.Add("Id", typeof(int));
foreach (var id in input)
{
    dataTable.Rows.Add(id);
}

var sql = @"
DECLARE @tempTable TABLE (Id INT);
INSERT INTO @tempTable (Id)
SELECT Id FROM @Ids; -- 从表值参数中读取数据插入
SELECT * FROM @tempTable;"; 

using (var connection = new SqlConnection(FiddleHelper.GetConnectionStringSqlServer())) 
{ 
    // 传入表值参数,指定对应SQL端的类型名称
    output = connection.Query<int>(sql, new { Ids = dataTable.AsTableValuedParameter("IntList") }).ToList(); 
}

如果不想创建自定义表值类型,也可以用Dapper的自动批量展开语法,但要注意SQL Server默认限制INSERT ... VALUES的行数为1000,超过会触发报错,仅适合小量数据:

var sql = @"
DECLARE @tempTable TABLE (Id INT);
INSERT INTO @tempTable (Id) VALUES @Ids; -- Dapper会自动将列表展开为(1),(2),(3)...格式
SELECT * FROM @tempTable;"; 

using (var connection = new SqlConnection(FiddleHelper.GetConnectionStringSqlServer())) 
{ 
    output = connection.Query<int>(sql, new { Ids = input }).ToList(); 
}

二、关于Dapper区分本地SQL变量与参数的疑问

答案是完全可以区分。Dapper只会识别并替换你传入的参数对象(比如new { Ids = input })中存在的@前缀变量,而SQL语句里通过DECLARE声明的本地变量(比如@tempTable)会被原样保留,不会被Dapper处理。简单来说,Dapper的参数匹配是基于你传入的参数键名,而非所有@开头的字符串,不用担心二者混淆。

内容的提问来源于stack exchange,提问作者PajLe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 12:42:44