Я не могу получить выходной параметр при использовании функции 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, если это не нужно, когда это необходимо, оно должно быть отменено, но обязательно объявите его правильно или оно может не работать.