使用实体框架导入函数时无法获取输出参数

发布于 2024-11-05 03:55:55 字数 541 浏览 0 评论 0原文

这是我的 SQL Server 存储过程:

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

和我的 C# 代码

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

但是 outputParameter.Value 始终为 null。

有人能告诉我为什么吗?

Here's my SQL Server stored procedure :

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

And my C# code

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

However outputParameter.Value always is null.

Could anybody tell me why?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

-残月青衣踏尘吟 2024-11-12 03:55:55

存储过程执行期间输出参数由其实际值填充。

但是表值存储过程实际上仅在您尝试迭代结果记录集而不是调用包装器方法时才会执行。

所以,这不起作用:

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's actual value
    Response.Write(outputParameter.Value); 

} 

当您使用不返回任何记录集的存储过程时,它们会在方法调用后立即执行,因此您在输出参数中有实际值。

Output parameters filled by its actual values during the execution of the stored procedure.

But table-valued stored procedure actually get executed only in moment when you're trying to iterate resulting recordset, but not calling a wrapper method.

So, this DOES'T work:

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

} 

This DOES:

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's actual value
    Response.Write(outputParameter.Value); 

} 

When you're working with stored procedures what don't return any recordset, they execute immediately after a method call, so you have actual value in output parameter.

塔塔猫 2024-11-12 03:55:55

我以前也有同样的问题。我认为实体框架存在错误的主要原因是用户存储过程有输出参数并返回结果集。例如:

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

如果有人有更好的解决方案,请告诉我

I have same problem before. The main reason I think that the entities framework has the bug in case the user stored procedure has output parameter and return a result set. For example:

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

However if you change the user stored procedure as following, you can get the output params

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

You can workaround as following:

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

If anybody has better solution, please tell me

余厌 2024-11-12 03:55:55

由于延迟执行,我们的单元测试失败了,我们遇到了类似的问题。简而言之,如果您有一个不返回任何内容的存储过程,请确保将响应类型设置为“无”,当设置为“无”时,它将在调用时执行,而不是延迟。

如果您返回任何内容(例如字符串结果的标量类型),当您使用结果时,即使 .Count() 或 .ToList() 位于包含函数调用的方法之外,它也会执行它 >。

所以不需要的时候尽量不要强制执行,需要的时候应该执行,但是一定要声明正确,否则可能会不起作用。

We had a simular issue due to defered excecution our unit tests failed. In short if you have a stored proc that does NOT return anything you need to be sure to set the response type as 'None' when set as 'None' it will be excecuted when called and not defered.

In case you return anything (E.g. Scalar type of String results) it will excecute it when you use the result even if that .Count() or .ToList() is outside of the method that contains the function call.

So try not to force excecution if not need, when needed it should excecute but be sure to declare it correctly or it might not work.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文