【问题标题】:I cannot get the output parameter when use function import by Entity Framework使用实体框架导入函数时无法获取输出参数
【发布时间】:2011-05-04 09:32:10
【问题描述】:

这是我的 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 始终为空。

谁能告诉我为什么?

【问题讨论】:

  • 我们需要查看TestDBEntities。此外,您需要将 outputParameter 作为输出传递以获得任何结果。
  • 问题是 TestDBEntities 无法在您调用它时返回 outputParameter。因此,我需要看看 TestDBEntities.SearchUser 是如何定义的。否则我无法回答问题。
  • 对不起,我不会从陌生网站下载。我建议你看看它。
  • 谢谢,请忘记这个问题

标签: stored-procedures linq-to-entities


【解决方案1】:

在存储过程执行过程中,输出参数由其实际值填充。

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

所以,这不起作用:

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

} 

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

【讨论】:

  • 谢谢,这对我有帮助。看来我们必须在读取输出参数的值之前将结果放入列表中
  • 非常感谢您的帮助,您节省了我数小时的搜索时间
  • 如果你有一个 int 返回类型而不是一个列表呢?
  • 我相信您不能将 int 作为表值存储过程的返回类型。例如,如果您仅通过 SELECT 1 返回某些内容,那么您将获得一个只有一个元素的 List
  • 当然,可以将其合并为: context.SearchUser("", outputParameter).ToList();
【解决方案2】:

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

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

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

【讨论】:

  • 将响应类型设置为“无”?在哪里?代码?
  • @JamesBailey - 实体框架设计者有一个模型浏览器和相关的属性表。在此属性表中,您可以将存储过程实体框架函数导入的导入函数返回类型设置为无。当然,这假设数据库优先方法。如果先使用代码,我不确定如何进行此设置...
【解决方案3】:

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

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

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

【讨论】:

  • 现在好像不是这样了。
  • 我认为第二个答案更好地解释了事情
猜你喜欢
  • 2018-09-26
  • 1970-01-01
  • 1970-01-01
  • 2011-04-26
  • 1970-01-01
  • 1970-01-01
  • 2011-07-24
  • 2016-08-26
  • 1970-01-01
相关资源
最近更新 更多