2013-05-06 8 views
6

質問

Entity Framework 4.4およびC#4.0を使用してストアドプロシージャの「結果」、「メッセージ」、および「戻り値」にアクセスするにはどうすればよいですか?Entity Framework 4を使用してストアドプロシージャの「結果」、「メッセージ」、および「戻り値」にアクセスする方法は?

以下は、3つのパラメータを使用するストアドプロシージャです。私がStoreプロシージャを実行するときには、「結果」、「メッセージ」、および「戻り値」の3つの値すべてにアクセスできる必要があります。

誰かがEFでそれを行う方法を理解できますか?私がアクセスできるように見えるすべてがクエリの[結果](返された行)

ストアドプロシージャ

USE [THIS_DB] 
GO 

SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 

ALTER PROCEDURE [dbo].[THIS_PROCEDURE] 
    @FIRST_PARAM CHAR(17) = NULL, 
    @SECOND_PARAM CHAR(2) = NULL, 
    @THIRD_PARAM CHAR(5) = NULL 
AS 
BEGIN 
    SET NOCOUNT ON; 
    DECLARE @ReturnValue INT = 0; 
    IF COALESCE(@SECOND_PARAM, 'XX') NOT IN ('XX', 'YY') 
    BEGIN 
     RAISERROR('Invalid @SECOND_PARAM value: %s; @SECOND_PARAM mXXt be XX or YY.', 2, 1, @SECOND_PARAM) WITH SETERROR; 
     SET @ReturnValue = -50100; 
    END 
    IF COALESCE(@SECOND_PARAM, 'XX') = 'YY' 
    BEGIN 
     RAISERROR('@SECOND_PARAM value: %s; YY is valid, but currently is not supported, returning XX results.', 2, 1, @SECOND_PARAM) WITH SETERROR; 
     SET @ReturnValue = -50105; 
    END 
    IF COALESCE(@THIRD_PARAM, 'XX-EN') NOT IN ('XX-EN') 
    BEGIN 
     RAISERROR('Invalid @THIRD_PARAM value: %s; @THIRD_PARAM mXXt be XX-EN.', 2, 1, @THIRD_PARAM) WITH SETERROR; 
     SET @ReturnValue = -50101; 
    END 
    SELECT DISTINCT 
     THESE.VALUES 
     FROM dbo.THIS_TABLE 
     WHERE THESE.CONDITIONS; 

    IF @@ROWCOUNT = 0 
    BEGIN 
     DECLARE @SP_MATCHCOUNT INT 

     EXEC @SP_MATCHCOUNT = [dbo].[MATCHTABLE] @PATTERNH = @PATTERN 
     IF @SP_MATCHCOUNT > 0 
     BEGIN 
      RAISERROR('Mapping from HERE to HERE not found for PATTERN: %s.', 2, 1, @PATTERN) WITH SETERROR 
      SET @ReturnValue = -50103; 
     END 
     ELSE 
     BEGIN 
      RAISERROR('PATTERN Pattern not found for PATTERN: %s.', 2, 1, @PATTERN) WITH SETERROR 
      SET @ReturnValue = -50104; 
     END 
    END 
    RETURN @ReturnValue 
END 

はCODE

public virtual ObjectResult<THIS_PROCEDURE_RESULT> THIS_PROCEDURE_METHOD(string FIRST, string SECOND, string THIRD) 
{ 
    var FIRST_PARAM = FIRST != null ? 
     new ObjectParameter("FIRST", FIRST) : 
     new ObjectParameter("FIRST", typeof(string)); 

    var SECOND_PARAM = SECOND != null ? 
     new ObjectParameter("SECOND", SECOND) : 
     new ObjectParameter("SECOND", typeof(string)); 

    var THIRD_PARAM = THIRD != null ? 
     new ObjectParameter("THIRD", THIRD) : 
     new ObjectParameter("THIRD", typeof(string)); 

    return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<THIS_PROCEDURE_RESULT>("THIS_PROCEDURE", FIRST_PARAM, SECOND_PARAM, THIRD_PARAM); 
} 
+0

EFでこの問題が発生しました。保存されたprocsの戻り値が返されないのは、EF 6.1.3で修正されましたか? – Kixoka

答えて

11

あるEFの外に生成されたコードを使用しますだから、最初のことが最初に:-)私は質問の3つの部分に答える前に私たちが同じページにいることを確認したい。 EFはORM(オブジェクト・リレーショナル・マッパー)として設計されています。つまり、存在するための目的は、リレーショナルデータをコードオブジェクトに変換することです(逆も同様です)。このために使用するメカニズムは、結果セット(戻り値ではありません)です。したがって、EF内の配管のほとんどは、結果セットを操作し、その結果セットを取得するためのSQLを自動的に生成するように特別に設計されています。しかし、人々がそれを要求して以来、EFは現在、ストアドプロシージャを実行する能力を持っていますが、その能力は包括的ではなく、製品の主な機能の副作用のようなものです。つまり、EFはADO.NETを使用しています。これは、ADO.NETがすべてのシナリオを処理するため、答えを得る場所です。

最初の問題 - 結果を得る方法。この場合、EFはSPを実行し、おそらく、結果列に一致するプロパティを持つオブジェクトにマップされます。つまり、EFはオブジェクトのコレクション(より正確な列挙可能なクエリ結果)を作成します。各オブジェクトは結果のデータ行を表します。あなたの場合、メソッドの戻り値はObjectResultです。 ObjectResultはオブジェクトのコレクションであり、各アイテムはTHIS_PROCEDURE_RESULT型であり、結果として各マッピングされた列のプロパティを持ちます。

第2の問題 - メッセージを取得する方法。特定の範囲の重大度でRaiserrorを使用すると、ADO.NETがスローされ、例外(SqlException型)が発生します。 EFは、そのエラーをただ表面化(通過)します。そのSQLExceptionインスタンスにはすべてのエラー&メッセージ情報が含まれます。それを見て、あなただけのエラーをキャッチする必要があります。

try 
{ 
    // call EF SP method here... 
} 
catch(SqlException se) 
{ 
    Debug.WriteLine(se.Message); 
} 
catch(Exception e) 
{ 
    // all non-DB errors will be seen here... 
} 

をRAISERROR文が警告または情報の重要度である場合には、ADO.NETは、例外をスローしません。その場合、接続オブジェクトのイベントを使用して、データベースからの情報および警告メッセージを表示する必要があります。 EFでこれを行うには、EFオブジェクトコンテキストからEntityConnectionを取得してから、EntityConnectionからストア接続を取得する必要があります。 SQL Server(SqlClient ADO.NETプロバイダ)を使用している場合、これはSqlConnectionインスタンスになります。そのインスタンスには、InfoMessageというイベントが含まれています。そのイベントにイベントハンドラを接続して、メッセージをトラップすることができます。詳細情報:http://support.microsoft.com/kb/321903

最後の問題 - 戻り値を取得する方法。これは吸うつもりです。私の最初の段落に基づいて、EFは実際にSPコールを任意に処理するようには設計されていません。結果セットはオブジェクトコレクションにマップしますが、SPからの戻り値は処理しません。 SqlCommandオブジェクトのParametersコレクションにアクセスするには、EFレイヤーなしでADO.NETを使用する必要があります。パラメータの1つはパラメータ型ReturnValueであり、戻り値そのものを含みます。

+0

このような詳細な回答をありがとうございます。あなたの時間は非常に高く評価されています。 – newSingleton

関連する問題