如何使用 Dapper 将 list<myobject> 作为参数插入到存储过程
Posted
技术标签:
【中文标题】如何使用 Dapper 将 list<myobject> 作为参数插入到存储过程【英文标题】:How do I use Dapper to insert a list<myobject> as parameter to a stored procedure 【发布时间】:2021-12-25 21:27:50 【问题描述】:我有一个包含 10 列的 SQL Server 表:
CREATE TABLE [bank].[CommonPostingsFromBankFiles]
(
[Id] [INT] IDENTITY(1,1) NOT NULL,
[BankRegistrationNumber] [INT] NOT NULL,
[BankAccountNumber] [BIGINT] NOT NULL,
[BankName] [NVARCHAR](50) NULL,
[BankAccount] [NVARCHAR](50) NULL,
[PostingAmount] [DECIMAL](18, 2) NOT NULL,
[PostingDate] [DATE] NOT NULL,
[Primo] [CHAR](1) NULL,
[PostingText] [NVARCHAR](100) NULL,
[HideThisRecord] [BIT] NULL,
CONSTRAINT [PK_CommonPostingsFromBankFiles]
PRIMARY KEY CLUSTERED ([BankRegistrationNumber] ASC,
[BankAccountNumber] ASC,
[PostingAmount] ASC,
[PostingDate] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
)
还有一个需要 7 个参数的存储过程:
ALTER PROCEDURE [bank].[spInsertCommonPostings]
(@BankRegistrationNumber INT,
@BankAccountNumber BIGINT,
@BankName NVARCHAR(50),
@PostingAmount DECIMAL(18, 2),
@PostingDate DATE,
@Primo CHAR(1),
@PostingText NVARCHAR(100))
AS
BEGIN
IF NOT EXISTS (SELECT *
FROM bank.CommonPostingsFromBankFiles
WHERE BankRegistrationNumber = @BankRegistrationNumber
AND BankAccountNumber = @BankAccountNumber
AND BankName = @BankName
AND PostingAmount = @PostingAmount
AND PostingDate = @PostingDate)
INSERT INTO bank.CommonPostingsFromBankFiles (BankRegistrationNumber, BankAccountNumber,
BankName, PostingAmount,
PostingDate, Primo, PostingText)
VALUES (@BankRegistrationNumber, @BankAccountNumber,
@BankName, @PostingAmount,
@PostingDate, @Primo, @PostingText);
END;
我想要的是使用 Dapper 使用存储过程将List<Postings>
写入表。
我已经搜索和搜索,但没有找到对我有帮助的示例。
如果我这样做
connection.Execute(sql: "spMyStoredProc", MyList, commandType: CommandType.StoredProcedure);
我收到一个错误
过程或函数 spMyStoredProc 指定的参数过多
如果我用存储过程中的 sql 替换存储过程的名称并将 CommandType 设置为 Text,它会按预期工作。
谁能给我发一个例子,展示如何使用我的存储过程插入我的列表。
谢谢, 史蒂芬
【问题讨论】:
如果要将对象列表传递给过程,则需要接受表值参数。您将需要定义一个类似于您的CREATE TABLE
的CREATE TYPE...AS TABLE...
并指示Dapper 识别它。此处举例说明:dapper-tutorial.net/parameter-table-valued-parameter
当您使用命令文本时,Dapper 可以从 SQL 中检查需要哪些属性。当您调用 SP 时,它不能 - 它必须假设声明的所有内容都是想要的 - 在这种情况下,假设是不正确的。或者基本上:“@Caius 说了什么”
【参考方案1】:
简单地说,假设您的 c# 对象中的属性名称与存储过程中的参数名称相同,您可以:
MyList.ForEach(x => connection.Execute(sql: "spMyStoredProc", x, commandType: CommandType.StoredProcedure));
如果参数/道具未对齐,则提供一个匿名类型可能是最简单的,该类型填充了来自 x 的值来覆盖它们
MyList.ForEach(x => connection.Execute(
sql: "spMyStoredProc",
new BankRegistrationNumber = x.BankRN, ... ,
commandType: CommandType.StoredProcedure
));
对于 10 个对象的列表,它将调用 proc 10 次;这不是最快的方法,但我认为您没有说明任何特定的目标和性能等。
【讨论】:
非常感谢!你的建议解决了我的问题。我的收藏包含大约 1.000 个元素,但我在上面花费 4 秒钟没有问题。以上是关于如何使用 Dapper 将 list<myobject> 作为参数插入到存储过程的主要内容,如果未能解决你的问题,请参考以下文章
使用Dapper时,如何将MySqlParameters[] 变成Dapper.DynamicParameters动态对象