Я не могу получить выходной параметр при использовании функции import по Entity Framework

Здесь хранится моя хранимая процедура SQL Server:

ALTER PROCEDURE [dbo].[SearchUser]
  (@Text NVARCHAR(100),  
   @TotalRows INT = 0 OUTPUT)   
AS
BEGIN 
   SELECT @TotalRows=1000
   SELECT * from Users
END

И мой код С#

using (var context = new TestDBEntities())
{
    var outputParameter = new ObjectParameter("TotalRows", typeof(Int32));
    context.SearchUser("", outputParameter);
    Response.Write(outputParameter.Value);
}

Однако outputParameter.Value всегда равно null.

Может ли кто-нибудь сказать мне, почему?

Ответы

Ответ 1

Параметры вывода, заполненные его фактическими значениями во время выполнения хранимой процедуры.

Но хранимая в таблице хранимая процедура фактически выполняется только в момент, когда вы пытаетесь выполнить итерацию результирующего набора записей, но не вызываете метод обёртки.

Итак, эта работа DOES'T:

using (var context = new TestDBEntities()) 
{ 
    var outputParameter = new ObjectParameter("TotalRows", typeof(Int32)); 
    context.SearchUser("", outputParameter); 

    // Paremeter value is null, because the stored procedure haven't been executed
    Response.Write(outputParameter.Value); 

} 

Это:

using (var context = new TestDBEntities()) 
{ 
    var outputParameter = new ObjectParameter("TotalRows", typeof(Int32)); 

    // Procedure does not executes here, we just receive a reference to the output parameter
    var results = context.SearchUser("", outputParameter);

    // Forcing procedure execution
    results.ToList();

    // Parameter has it actual value
    Response.Write(outputParameter.Value); 

} 

Когда вы работаете с хранимыми процедурами, что не возвращает какой-либо набор записей, они выполняются сразу после вызова метода, поэтому у вас есть фактическое значение в выходном параметре.

Ответ 2

У меня такая же проблема раньше. Основная причина, по которой я считаю, что инфраструктура сущностей имеет ошибку, если пользовательская хранимая процедура имеет выходной параметр и возвращает результат. Например:

ALTER PROCEDURE [dbo].[SearchTest]
(   
    @RowTotal   INT = 0 OUTPUT,
    @RowCount   INT = 0 OUTPUT
)
AS
BEGIN   
    SET NOCOUNT ON
    SELECT * FROM SomeThing 
    SELECT @RowTotal = 1233, @RowCount = 5343
END

Однако, если вы измените хранимую процедуру пользователя следующим образом, вы можете получить выходные параметры

ALTER PROCEDURE [dbo].[SearchTest]
(   
    @RowTotal   INT = 0 OUTPUT,
    @RowCount   INT = 0 OUTPUT
)
AS
BEGIN   
    SET NOCOUNT ON  
    SELECT @RowTotal = 1233, @RowCount = 5343
END

Вы можете обходным путем следующим образом:

ALTER PROCEDURE [dbo].[SearchTest]
AS
BEGIN   
    DECLARE @RowTotal INT, @RowCount INT

    SET NOCOUNT ON  
    SELECT @RowTotal = 1233, @RowCount = 5343

    SELECT @RowTotal  AS RowTotal, @RowCount AS RowCount, s.*
    FROM SomeThing s

END

Если у кого-то есть лучшее решение, скажите мне

Ответ 3

У нас была симулятивная проблема из-за отсроченного исключения, которое завершилось нашими модульными тестами. Короче говоря, если у вас есть сохраненный proc, который НЕ возвращает ничего, вам нужно установить тип ответа как "Нет" , когда он задан как "Нет", он будет отменен при вызове и не отсрочен.

Если вы вернете что-либо (например, Scalar type of String results), он будет отменять его, когда вы используете результат, даже если этот .Count() или .ToList() находится вне метода, который содержит вызов функции.

Поэтому старайтесь не принуждать к execcution, если это не нужно, когда это необходимо, оно должно быть отменено, но обязательно объявите его правильно или оно может не работать.