简体   繁体   English

如何使用Entity Framework 4访问存储过程的“结果”,“消息”和“返回值”?

[英]How to access 'Results', 'Messages', and 'Return Value' of a Stored Procedure using Entity Framework 4?

QUESTION

How do I access the 'Results', 'Messages', and 'Return Value' of a Stored Procedure using Entity Framework 4.4 and C# 4.0? 如何使用Entity Framework 4.4和C#4.0访问存储过程的“结果”,“消息”和“返回值”?

Below is the Stored Procedure that takes three parameters. 以下是带有三个参数的存储过程。 One way or another when I run the Store Procedure I should, I hope, be able to access all three values for 'Results', 'Messages', and 'Return Value'. 当我运行存储过程时,我希望能够以这样或那样的方式访问“结果”,“消息”和“返回值”的所有三个值。

Can someone help me figure out how to do that with EF? 有人可以帮我弄清楚如何用EF做到这一点吗? Using the code that is generated out of EF all I seem to be able to access is the 'Results' of the query ( returned rows ) 使用EF生成的代码,我似乎能够访问的是查询的“结果”(返回的行)

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);  
}  

So, first things first :-) Just want to make sure we're on the same page before I answer the 3 parts of the question. 所以,首先要做的事情是:-)只是想在回答问题的3个部分之前确保我们在同一页面上。 EF is designed to be an ORM (object-relational-mapper). EF被设计为ORM(对象关系映射器)。 That means its purpose for being is to translate relational data to code objects (and vice-versa). 这意味着它的目的是将关系数据转换为代码对象(反之亦然)。 The mechanism it uses for this is result sets (not return values). 它用于此的机制是结果集(不是返回值)。 So most of the plumbing inside EF is specifically designed to operate on result sets, and also to automatically generate SQL for getting those result sets. 因此,EF中的大部分管道都是专门设计用于对结果集进行操作,也是为了获取这些结果集而自动生成SQL。 However, since people requested it, EF now has the capability to execute stored procedures, but that ability is not comprehensive, and is sort of a side-effect to the main capabilities of the product. 但是,由于人们要求它,EF现在具有执行存储过程的能力,但是这种能力并不全面,并且对产品的主要功能有一种副作用。 Having said that, EF does use ADO.NET under the covers, and that's where you are going to get your answers because ADO.NET does handle all your scenarios. 话虽如此,EF确实使用了ADO.NET,这就是你要获得答案的地方,因为ADO.NET确实可以处理你的所有场景。

First problem - how to get results. 第一个问题 - 如何获得结果。 EF will execute the SP in this case, and presumably, it's mapped to some object that has properties that match the result columns. 在这种情况下,EF将执行SP,并且可能会将其映射到具有与结果列匹配的属性的某个对象。 That means that EF will create a collection (enumerable query result set to be more precise) of objects, each of which represents a row of data in the results. 这意味着EF将创建一个对象的集合(可枚举的查询结果集更精确),每个对象代表结果中的一行数据。 In your case, the return of your method is ObjectResult. 在您的情况下,您的方法的返回是ObjectResult。 ObjectResult is a collection of objects, and each item is of type THIS_PROCEDURE_RESULT, which in turn has a property for each mapped column of the result. ObjectResult是一个对象集合,每个项目的类型为THIS_PROCEDURE_RESULT,而后者又为结果的每个映射列都有一个属性。

Second problem - how to get messages. 第二个问题 - 如何获取消息。 If Raiserror is used with a certain range of severity, will cause ADO.NET to throw and exception (of type SqlException). 如果使用Raiserror具有一定范围的严重性,将导致ADO.NET抛出异常(类型为SqlException)。 EF will just just surface (pass through) that error. EF只是表面(通过)该错误。 That SQLException instance will contain all the error & message information. 该SQLException实例将包含所有错误和消息信息。 To see it, you just have to catch the error: 要查看它,您只需捕获错误:

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

However, if the Raiserror statement is of a warning or info severity, ADO.NET will not throw an exception. 但是,如果Raiserror语句具有警告或信息严重性,则ADO.NET不会抛出异常。 In that case, you have to use an event of the connection object to see info and warning messages from the databse. 在这种情况下,您必须使用连接对象的事件来查看数据库中的信息和警告消息。 To do this in EF, you have to get the EntityConnection from the EF object context, and then get the Store Connection from the EntityConnection. 要在EF中执行此操作,您必须从EF对象上下文获取EntityConnection,然后从EntityConnection获取存储连接。 If you are using SQL Server (SqlClient ADO.NET provider), this will be a SqlConnection instance. 如果您使用的是SQL Server(SqlClient ADO.NET提供程序),那么这将是一个SqlConnection实例。 That instance contains an event called InfoMessage. 该实例包含一个名为InfoMessage的事件。 You can hook up an event handler to that event to trap messages. 您可以将事件处理程序连接到该事件以捕获消息。 More info here: http://support.microsoft.com/kb/321903 有关详细信息,请访问: http//support.microsoft.com/kb/321903

Last problem - how to get Return Value. 最后一个问题 - 如何获得回报值。 This one is going to suck. 这个会很糟糕。 Based on my first paragraph, EF isn't really designed to arbitrarily handle SP calls. 根据我的第一段,EF并不是真正设计为任意处理SP调用。 While it will map result sets to object collections, it doesn't handle return values from SPs. 虽然它会将结果集映射到对象集合,但它不处理来自SP的返回值。 You will have to use ADO.NET without the EF layer in order to access the Parameters collections of the SqlCommand object. 您必须使用不带EF层的ADO.NET才能访问SqlCommand对象的Parameters集合。 One of the parameters is of parameter-type ReturnValue, and it will contain the return value itself. 其中一个参数是参数类型ReturnValue,它将包含返回值本身。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 不使用实体框架时如何将存储过程结果返回到类列表中? - How to return stored procedure results into a List of Class when not using entity framework? 使用实体框架调用存储过程总是返回相同的值 - Using Entity framework calling stored procedure return same value always 如何使用返回值参数执行Entity Framework SQLQuery存储过程? - How to execute Entity Framework SQLQuery stored procedure with return value parameter? 实体框架:如何运行存储过程并返回值? - Entity Framework: how do I run a stored procedure and return a value? 实体框架 - 存储过程返回值 - Entity Framework - stored procedure return value 如何在实体框架中检查存储过程的返回值 - how can i check return value of stored procedure in entity framework 存储过程的返回值在实体框架中为int - Stored procedure return value is int in entity framework 实体框架7 FromSql存储过程返回值 - Entity Framework 7 FromSql stored procedure return value 如何使用实体框架检索从存储过程返回的值? - How to retrieve a value returned from a stored procedure using entity Framework? 如何 map 来自 postresql 中的存储过程的结果集,我使用 Entity Framework Core 返回多个游标 - How to map set of results from stored procedure in postresql where I return multiple cursors using Entity Framework Core
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM