2013-05-06 6 views
6

Wie greife ich auf 'Ergebnisse', 'Nachrichten' und 'Rückgabewert' einer gespeicherten Prozedur mit Entity Framework 4.4 und C# 4.0?Zugriff auf 'Ergebnisse', 'Nachrichten' und 'Rückgabewert' einer gespeicherten Prozedur mit Entity Framework 4?

Unten ist die gespeicherte Prozedur, die drei Parameter verwendet. Auf die eine oder andere Weise, wenn ich die Store-Prozedur ausführe, sollte ich hoffentlich in der Lage sein, auf alle drei Werte für "Ergebnisse", "Nachrichten" und "Rückgabewert" zuzugreifen.

Kann mir jemand helfen, herauszufinden, wie man das mit EF macht? Mit dem Code, der aus EF erzeugt wird alles, was ich scheinen zugreifen zu können, ist es, die 'Ergebnisse' der Abfrage (zurückgegebenen Zeilen)

Stored Procedure

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

Wurde dieses Problem mit EF nicht zurückgegeben, gespeicherte Rückgabewerte wurden mit EF 6.1.3 behoben? – Kixoka

Antwort

11

Also, erste Dinge zuerst :-) Ich möchte nur sicherstellen, dass wir auf der gleichen Seite sind, bevor ich die 3 Teile der Frage beantworte. EF ist als ORM (object-relational-mapper) konzipiert. Das heißt, sein Zweck ist es, relationale Daten in Code-Objekte zu übersetzen (und umgekehrt). Der dafür verwendete Mechanismus ist Ergebnismengen (keine Rückgabewerte). Die meisten Installationen in EF wurden speziell für das Arbeiten mit Ergebnismengen entwickelt und generieren automatisch SQL, um diese Ergebnismengen zu erhalten. Seit die Leute es angefordert haben, ist EF nun in der Lage, gespeicherte Prozeduren auszuführen, aber diese Fähigkeit ist nicht umfassend und ist eine Art Nebeneffekt für die Hauptfunktionen des Produkts. Abgesehen davon verwendet EF ADO.NET unter den Deckblättern, und hier erhalten Sie Ihre Antworten, da ADO.NET alle Ihre Szenarien behandelt.

Erstes Problem - wie man Ergebnisse erhält. EF wird in diesem Fall den SP ausführen, und vermutlich wird es einem Objekt zugeordnet, das Eigenschaften hat, die den Ergebnisspalten entsprechen. Das bedeutet, dass EF eine Auflistung von Objekten erstellt, die jeweils eine Zeile mit Daten in den Ergebnissen darstellen. In Ihrem Fall ist die Rückgabe Ihrer Methode ObjectResult. ObjectResult ist eine Auflistung von Objekten, und jedes Element hat den Typ THIS_PROCEDURE_RESULT, der wiederum eine Eigenschaft für jede zugeordnete Spalte des Ergebnisses aufweist.

Zweites Problem - wie Nachrichten erhalten. Wenn Raiserror mit einem bestimmten Schweregrad verwendet wird, verursacht ADO.NET das Auslösen und die Ausnahme (vom Typ SqlException). EF wird gerade diesen Fehler aufdecken (durchgehen). Diese SQLException-Instanz enthält alle Fehlerinformationen &. Um es zu sehen, müssen Sie nur noch die Fehler abzufangen:

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

Wenn jedoch die RAISERROR-Anweisung einer Warnung oder Info Schwere ist, ADO.NET wird keine Ausnahme aus. In diesem Fall müssen Sie ein Ereignis des Verbindungsobjekts verwenden, um Informationen und Warnmeldungen aus der Datenbank zu sehen. Um dies in EF zu tun, müssen Sie die EntityConnection aus dem EF-Objektkontext abrufen und dann die Store-Verbindung von der EntityConnection abrufen. Wenn Sie SQL Server (SqlClient ADO.NET-Provider) verwenden, handelt es sich um eine SqlConnection-Instanz. Diese Instanz enthält ein Ereignis namens InfoMessage. Sie können einen Ereignishandler mit diesem Ereignis verbinden, um Nachrichten abzufangen. Weitere Infos hier: http://support.microsoft.com/kb/321903

Letztes Problem - wie man den Rückgabewert bekommt. Dieser wird absaugen. Basierend auf meinem ersten Absatz, EF ist nicht wirklich entworfen, um SP-Aufrufe willkürlich zu behandeln. Während Ergebnismengen Objektsammlungen zugeordnet werden, werden Rückgabewerte von SPs nicht verarbeitet. Sie müssen ADO.NET ohne die EF-Ebene verwenden, um auf die Parameters-Auflistungen des SqlCommand-Objekts zugreifen zu können.Einer der Parameter hat den Parametertyp ReturnValue und enthält den Rückgabewert selbst.

+0

Vielen Dank für die ausführliche Antwort. Ihre Zeit wird sehr geschätzt. – newSingleton

Verwandte Themen