使用 Dapper 的测试版,我发现这很有魅力:
result = dbConnection.ExecuteScalar<int>(typeof(UCCCCException).Name + "_c",
obj, commandType: CommandType.StoredProcedure);
我正在编写一个泛型,用于将任何类型的对象插入数据库。
存储过程如下所示:
ALTER PROCEDURE [dbo].[UCCCCException_c]
(
@Id int = null,
@ExceptionDate datetime = null,
@HResult int = 0,
@Message varchar(8000) = null,
@Source varchar(8000) = null,
@StackTrace varchar(8000) = null,
@Module varchar(8000) = null,
@Name varchar(8000) = null,
@created_at datetime = null,
@updated_at datetime = null,
@created_by int = null,
@updated_by int = null
,
@Creator varchar(255) = null,
@Updator varchar(255) = null
)
AS
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
Insert into dbo.uccccexceptions ( ExceptionDate, HResult, [Message], [Source], StackTrace, Module, Name)
values (
coalesce(@ExceptionDate,getdate()),
@HResult,
@Message,
@Source,
@StackTrace,
@Module,
@Name
)
;
select @@Identity;
go
需要注意的是,即使目标表中不存在这些属性,您也必须为正在使用的类中的每个属性指定一个条目作为存储过程的参数。如果您有许多在 MVC 情况下是视图字段的字段,这可能会很烦人。
要获得返回值,您只需要使用 Execute,并确保您的最后一条语句是在存储过程中选择 @@Identity。
它工作得很好,并允许我在我的存储库中编写一个通用的插入命令,如下所示:
public virtual int Insert(T obj)
{
int result = -2;
if (!databaseOnline)
{
throw new Exception(HttpStatusCode.ServiceUnavailable.ToString());
}
if (obj != null)
{
try
{
using (IDbConnection dbConnection = ConnectionProvider.OpenConnection())
{
dbConnection.Open();
result = dbConnection.ExecuteScalar<int>(typeof(T).Name + "_c",
obj, commandType: CommandType.StoredProcedure);
}
}
catch (SqlException sqlex)
{
Logger.LogError(sqlex, false);
throw;
}
catch (Exception ex)
{
Logger.LogError(ex);
throw;
}
}
return result;
}
我在我的数据库中使用约定,存储过程的名称是类型名称,后跟“_s”表示选择,“_c”表示插入,“_d”表示删除,“_u”表示更新。
PS:我讨厌使用 Dapper 的 DynamicParameters 或任何其他需要您为通用存储库中的每个类使用不同的插入或更新方法的设备。