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を使用し、最後のステートメントがストアドプロシージャのSelect@@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や、汎用リポジトリ内のクラスごとに異なる挿入または更新メソッドを使用する必要があるその他のデバイスを使用するのは嫌いです。