[英]Dapper return inserted value using stored procedures
我有一个 class 从 SQL 服务器插入和加载任何 model:
public class SqlDataAccess : ISqlDataAccess
{
private readonly IConfiguration _configuration;
public SqlDataAccess(IConfiguration configuration)
{
_configuration = configuration;
}
public async Task<IEnumerable<T>> LoadData<T, U>(string storedProcedure,
U parameters,
string connectionId = "Default")
{
using IDbConnection connection = new SqlConnection(_configuration.GetConnectionString(connectionId));
return await connection.QueryAsync<T>(storedProcedure,
parameters,
commandType: CommandType.StoredProcedure);
}
public async Task SaveData<T>(string storedProcedure,
T parameters,
string connectionId = "Default")
{
using IDbConnection connection = new SqlConnection(_configuration.GetConnectionString(connectionId));
await connection.ExecuteAsync(storedProcedure,
parameters,
commandType: CommandType.StoredProcedure);
}
}
它们都是调用存储过程的函数,例如:
CREATE PROCEDURE [dbo].[spAuthors_Insert]
@FirstName NVARCHAR(46),
@LastName NVARCHAR(46)
AS
BEGIN
INSERT INTO [dbo].[Authors] (FirstName, LastName)
VALUES (@FirstName, @LastName);
END
它使用下表:
CREATE TABLE [dbo].[Authors]
(
[Id] INT NOT NULL PRIMARY KEY IDENTITY,
[FirstName] NVARCHAR(46),
[LastName] NVARCHAR(46)
)
要插入作者,我使用以下 function:
public Task InsertAuthor(AuthorModel author) => _db.SaveData("dbo.spAuthors_Insert", new { author.FirstName, author.LastName });
现在我需要进行更改,以便当我插入作者时它返回带有 id 的寄存器,我尝试更改QueryFirstAsync
但它不会返回 model。 我可以改变什么来使这个通用的 function 返回保存的寄存器?
另外附带说明一下, LoadData
function 是否可以传递多个模型,以便在使用具有以下连接的存储过程时可以拆分它们:
CREATE PROCEDURE [dbo].[spArts_GetByUserId]
@Id NVARCHAR(256)
AS
BEGIN
SELECT *
FROM [dbo].[Arts]
INNER JOIN [dbo].[Registrations] ON [dbo].[Arts].id = [dbo].[Registrations].ArtId
INNER JOIN [dbo].[Arts_details] ON [dbo].[Arts].Arts_details_id = [dbo].[Arts_details].Id
INNER JOIN [dbo].[Authors] ON [dbo].[Arts_details].AuthorId = [dbo].[Authors].Id
WHERE UserId = @Id;
END
一个简单的获取示例:
public async Task<ArtsModel?> GetArt(int id)
{
var result_art = await _db.LoadData<ArtsModel, dynamic>("dbo.spArts_Get", new { Id = id });
var art = result_art.FirstOrDefault();
return art;
}
(因为您的“spAuthors_Insert”是基于单行的(而不是基于集合),您可以执行以下操作)。
您的存储过程需要执行 SELECT。 (作为它的最后一条指令)。 使用以下三个“身份”功能之一的 select。
以下三个之一:(可能按优先顺序,请参阅: Scope_Identity()、Identity()、@@Identity 和 Ident_Current() 之间有什么区别? )
SELECT SCOPE_IDENTITY()
或者
SELECT IDENT_CURRENT('tablename')
或者
SELECT @@IDENTITY
(您的表名是“作者”)
..
然后你的 ExecuteAsync
可能需要
ExecuteScalar(异步)
因为您需要获取该单列/行值。
从文档中:
ExecuteScalar() 的异步版本,它执行命令并返回第一个返回结果集中第一行的第一列。 所有其他列、行和结果集都将被忽略。
注意“第一行的第一列”。 (也不要错过“第一个返回的结果集”)。
(又名,确保存储过程中唯一的“选择”是上述三个 IDENTITY 函数之一。
并在 c# 代码上“点 i”。
Task SaveData<T>(
我会改为:
Task<long> SaveSingle<T>(
或者可能
Task<K> SaveSingle<T,K>(
(以上是本意,方法上的generics定义我还没试过。
其中 K 是“int”或“long”(ms-sql-server 中的 INT、BIGINT)......并且您返回新的 PrimaryKey。
并将.ExecuteScalarAsync的结果转换为long或K。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.