我必须处理一个特殊的遗留存储过程,该过程可能会导致参照完整性规则失败,从而产生运行时错误,仍会返回包含有效数据的结果集。为了说明这一点,这里有一个简短的设置脚本:
CREATE TABLE ParentRecord (
Id INT NOT NULL PRIMARY KEY,
HeaderText VARCHAR(100)
);
GO
CREATE TABLE DetailRecord (
Id INT NOT NULL IDENTITY(1, 1) PRIMARY KEY,
ParentId INT NOT NULL REFERENCES ParentRecord(Id),
DetailText VARCHAR(100)
);
GO
CREATE PROCEDURE InsertDetailRecord
@ParentId INT,
@DetailText VARCHAR(100)
AS
INSERT INTO dbo.DetailRecord (ParentId, DetailText) VALUES (@ParentId, @DetailText);
SELECT @ParentId AS ParentId, SCOPE_IDENTITY() AS DetailId;
GO
INSERT INTO dbo.ParentRecord(Id, HeaderText) VALUES (1, 'Existing parent');
GO
现在,如果我使用不存在的父ID执行存储过程,如下所示:
EXEC dbo.InsertDetailRecord @ParentId=2, @DetailText='Orphaned since birth';
SQL Server生成以下输出:
Msg 547, Level 16, State 0, Procedure InsertDetailRecord, Line 7
The INSERT statement conflicted with the FOREIGN KEY constraint "FK__DetailRec__Paren__4FE7E4DD". The conflict occurred in database "test", table "dbo.ParentRecord", column 'Id'.
The statement has been terminated.
ParentId DetailId
----------- ---------------------------------------
2 NULL
(1 row(s) affected)
(事实上,如果这样的过程是通过例如SOAP端点公开的,那么生成的SOAP信封将携带错误的消息和带有数据的RowSet元素,就像没有发生任何事情一样,但是永远都没有)
现在,我们可以使用Dapper调用此过程,类似于
var reader = Session.Connection.QueryMultipleAsync(storedProcedureName, parameters.ToDynamicParameters(), commandType: CommandType.StoredProcedure, transaction: GetTransaction(Session));
当我们最终开始浏览返回的读者对象时
while (!reader.IsConsumed)
{
result.Add(await reader.ReadAsync());
}
一切都爆发成火热的混乱(抛出异常,引用从SP返回的引用完整性错误)。
我的问题是:有没有办法以某种方式保存和读取带有2和NULL的小数据集,这实际上也是由程序返回的?