Dapper:它可以处理失败和返回数据的存储过程

时间:2017-03-09 10:40:19

标签: sql sql-server stored-procedures dapper

我必须处理一个特殊的遗留存储过程,该过程可能会导致参照完整性规则失败,从而产生运行时错误仍会返回包含有效数据的结果集。为了说明这一点,这里有一个简短的设置脚本:

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的小数据集,这实际上也是由程序返回的?

0 个答案:

没有答案