13

ストアドプロシージャを呼び出してusing Dapper.Net戻り値を取得しようとしています。

p.Add("@INCIDENT_ID", dbType: DbType.Int32, direction: ParameterDirection.ReturnValue);

var retResults = con.Execute("usp_GetIncidentID", p, commandType:CommandType.StoredProcedure);

int IncidentID = p.Get<int>("INCIDENT_ID"); 

パラメータの方向とを使用して、いくつかの異なることを試しました"@INCIDENT_ID"。結果を確認すると、適切な戻り値が値に含まれていることがわかりますがretResults、以下のドキュメントに記載されている方法で値にアクセスすることはできません。

ストアドプロシージャDapperは、完全にストアドプロシージャをサポートしています。

var user = cnn.Query<User>("spGetUser", new {Id = 1}, 
    commandType: CommandType.StoredProcedure).First();}}}
If you want something more fancy, you can do:

var p = new DynamicParameters();
p.Add("@a", 11);
p.Add("@b", dbType: DbType.Int32, direction: ParameterDirection.Output);
p.Add("@c", dbType: DbType.Int32, direction: ParameterDirection.ReturnValue);

cnn.Execute("spMagicProc", p, commandType: commandType.StoredProcedure); 

int b = p.Get<int>("@b");
int c = p.Get<int>("@c");   
4

6 に答える 6

7

これは、パラメーターの名前の付け方の純粋な不一致であると(未確認で)疑っています。試してください(削除されたことに注意してください@):

p.Add("INCIDENT_ID", dbType: DbType.Int32, direction: ParameterDirection.ReturnValue);

var retResults = con.Execute("usp_GetIncidentID", p, commandType:CommandType.StoredProcedure);

int IncidentID = p.Get<int>("INCIDENT_ID"); 
于 2013-01-10T07:58:39.013 に答える
2

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

于 2016-09-01T17:08:04.573 に答える
1

以下のように値を読み取ることができます

var incidentId = retResults.ToList()[0].INCIDENT_ID; 
于 2013-05-16T05:56:40.600 に答える
0

QueryMultipleの結果を読み取るときに同様の問題が発生しました。Read()への最初の呼び出しは正しいタイプを返し、2番目の呼び出しはDapperRowを返しました。型付きバージョンのRead()を使用していることがわかりました。

var lineExists = query.Read<int?>().FirstOrDefault() == 1;

私の問題を解決しました。

于 2014-01-02T20:26:54.197 に答える
0

簡単にするために、これを減らしました。返されるデータ型を完全に制御できるため、出力パラメーターを使用しています。このアプローチは、挿入だけでなく、他のシナリオでも使用できます。

ストアドプロシージャ:

ALTER PROCEDURE User_Insert (
@EmailAddress nvarchar(255),
@Id bigint OUT
) AS
INSERT INTO User (
        [EmailAddress]
    ) VALUES (
        @EmailAddress
    )
    set @Id = SCOPE_IDENTITY()

リポジトリコード:

var sql = "Execute User_Insert @EmailAddress, @Id = @Id OUTPUT";
var _params = new DynamicParameters();
_params.Add("EmailAddress", user.EmailAddress);
_params.Add("Id", dbType: DbType.Int64, direction: ParameterDirection.Output);

using (var connection = new SqlConnection(ConnectionString)) {
    connection.Open();
    using (var transaction = connection.BeginTransaction()) {
        var result = SqlMapper.Execute(connection, sql, param, transaction);
        transaction.Commit();
    }
}    
var id = _params.Get<long>("Id");
于 2014-05-13T19:22:13.150 に答える
0

DynamicParametersソリューションは私にはきれいではありません。ストアドプロシージャコードが整数を返すようにして(1を選択;)、dapperを使用する方がはるかに優れています。ExecuteScalar<int>("[sp_name]", params);

于 2017-05-30T07:18:17.110 に答える