2013-01-09 61 views
11

ストアドプロシージャusing Dapper.Netを呼び出して戻り値を取得しようとしています。ストアドプロシージャを使用した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のは、完全に保存されprocsのサポート:

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"); 
+0

「ドキュメントに記載されている方法で値にアクセスできません。」 – MethodMan

+1

試みました 'var IncidentID = con.Query (" usp_GetIncidentID "、commandType:CommandType.StoredProcedure).SingleOrDefault();'?これは最も簡単で、ストアドプロシージャが "select"を介して値を返す場合に機能します –

+0

これまで試したことがありますが、私は前に見てきた {DapperRow、INCIDENT_ID = '902306'}その値にアクセスしようとすると問題が発生します。 – yellowfever

答えて

0

私はQueryMultipleの結果を読んでも、同様の問題に遭遇した

var incidentId = retResults.ToList()[0].INCIDENT_ID; 
+2

空の結果セットを持つ戻り値を取得しようとすると機能しません! – alerya

5

私はこれは純粋には、パラメータに名前を付ける方法に不一致があると思われる(未テスト)を、 (削除@に注意してください)してみてください。

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"); 
+0

Marc、私は '@'記号で遊んでいました。どこか読んだところ違いがありましたが、それはありませんでした。私はウォッチウィンドウを見て、結果の値を見ることができるので、正しい値を取得しています。私は彼らに「正しい」方法を手に入れる方法を完全には分かっていません。例。 retResults = {DapperRow、INCIDENT_ID = '902479'} お返事ありがとうございます! – yellowfever

+0

結果はデー​​タグリッドになりますか?質問はあなたがパラメータを更新していることを示唆しました... –

+0

マーク、はい、その結果です。ドキュメントを理解しているので、戻り値の型が "ParameterDirection.ReturnValue"のパラメータとして値を渡すことになっています。結果は正しく返ってきて、私は "p.get (" INCIDENT_ID ")を使ってその結果にマップできません。 また、応答のお返事をありがとうございます。非常に感謝しています。 – yellowfever

0

以下のようにあなたが値を読み取ることができます。 Read()への最初の呼び出しは正しい型を返し、2番目の呼び出しはDapperRowを返しました。私は)(読むの型付きバージョンを使用していることが見つかりました:

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

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

+1

結果セットに0行があり、戻り値があればどうなりますか? – alerya

0

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

ストアドプロシージャ:

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

リポジトリーコード:

result = dbConnection.ExecuteScalar<int>(typeof(UCCCCException).Name + "_c", 
         obj, commandType: CommandType.StoredProcedure); 

私は書いている:Dapperののテストバージョンを使用して

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"); 
0

は、私はこれは魔法のように動作しました任意のタイプのオブジェクトをデータベースに挿入する際に使用する汎用オブジェクトです。

ストアドプロシージャは、次のようになります。この上

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であることを確認するだけです。

それは完璧に動作し、私はこのように私のリポジトリにジェネリックinsertコマンドを記述することができます:

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

0

DynamicParametersソリューションは私にはきれいではありません。ストアドプロシージャコードを整数(Select 1;)に戻してダッパーを使用するほうがはるかに良いですExecuteScalar<int>("[sp_name]", params);

関連する問題