C# 为什么SQL Server字符串输出参数在EF EXECUTESQLCOMAND调用时返回0?

C# 为什么SQL Server字符串输出参数在EF EXECUTESQLCOMAND调用时返回0?,c#,sql-server,entity-framework,C#,Sql Server,Entity Framework,我在C#中有这段代码,我想在代码中使用字符串sReturn作为输出参数 var sReturn = new SqlParameter(); sReturn.ParameterName = "@Return"; sReturn.SqlDbType = SqlDbType.VarChar; sReturn.Size = 300; sReturn.Direction = ParameterDirection.Output; string query = "exec @Return = sqlServ

我在C#中有这段代码,我想在代码中使用字符串
sReturn
作为输出参数

var sReturn = new SqlParameter();
sReturn.ParameterName = "@Return";
sReturn.SqlDbType = SqlDbType.VarChar;
sReturn.Size = 300;
sReturn.Direction = ParameterDirection.Output;

string query = "exec @Return = sqlServerProcedure @id, @dateBegin, @dateEnd";

_context.Database.CommandTimeout = timeout;
_context.Database.ExecuteSqlCommand
            (query, sReturn,
                new SqlParameter("@id", id),
                new SqlParameter("@dateBegin", dateBegin),
                new SqlParameter("@dateEnd", dateEnd) );
 return sReturn.Value;
sReturn
始终返回0

程序是这样的:

CREATE PROCEDURE [dbo].sqlServerProcedure 
     (@dateBegin DATETIME,
      @dateEnd DATETIME,
      @id NUMERIC)
AS
BEGIN
    SELECT 'some random message'
END

为什么它总是返回0?

错误出现在SQL Server过程中,并且在
ExecuteSqlCommand
中调用它

你必须在C中这样做:

在SQL Server中:

CREATE PROCEDURE [dbo].sqlServerProcedure 
    (@dateBegin DATETIME,
     @dateEnd DATETIME,
     @id NUMERIC,
     @Return VARCHAR(300) OUTPUT)

您确实不需要声明@return参数,如果您希望从过程中得到一个值,请使用SQL
命令的
ExecuteScalar()
方法

也可以使用存储过程类型而不是内联SQL查询。您的ADO.net代码如下所示,存储过程中没有更改

_context.Database.Connection.Open();
var cmd = _context.Database.Connection.CreateCommand();
cmd.CommandTimeout = timeout;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "sqlServerProcedure";
cmd.Parameters.Add(new SqlParameter("@id", id));
cmd.Parameters.Add(new SqlParameter("@dateBegin", dateBegin));
cmd.Parameters.Add(new SqlParameter("@dateEnd", dateEnd));
var result = (string)cmd.ExecuteScalar();
的文档包含以下内容:

@返回\u状态 是一个可选的整数变量,用于存储模块的返回状态。在EXECUTE语句中使用该变量之前,必须在批处理、存储过程或函数中声明该变量

当用于调用标量值用户定义函数时,@return\u状态变量可以是任何标量数据类型

由于调用的是存储过程(不是标量值函数),因此返回值0(成功)转换为字符串

如果您使用的是ADO.NET,那么您可以使用另一个答案中提到的
ExecuteScalar
。但是,EF6
ExecuteSqlCommand
方法与ADO.NET
ExecuteOnQuery
等效,不能用于检索返回的单行单列记录集

在EF6中执行存储过程并获得所需字符串结果的最简单方法是结合使用EF
SqlQuery
方法和LINQ
FirstOrDefault

var returnValue = _context.Database
    .SqlQuery<string>("sqlServerProcedure @p0, @p1, @p2", dateBegin, dateEnd, id)
    .FirstOrDefault();
var returnValue=\u context.Database
.SqlQuery(“sqlServerProcedure@p0、@p1、@p2”、dateBegin、dateEnd、id)
.FirstOrDefault();

我的问题是,为什么要使用sql命令执行此操作。是否可以将命令类型更改为存储过程?是否执行了任何命令?零表示不受任何行影响。0是存储过程的返回值,0表示成功。正如下面的@Vinit正确回答的那样,字符串值在结果集中返回,并且可以使用ExecuteReader()读取,或者,因为只有一行和一列,所以可以使用ExecuteScalar()。
\u上下文。数据库
不是
DbCommand
,并且没有
ExecuteScalar
方法(以及显示的其他属性).\u context.database没有executeScalarmethod@IvanStoev-没错,我忽略了这是一个实体数据库上下文,而不是SQL命令。您的答案应该是解决方案。@Vinit是的,ORM及其局限性:)@DavidBrowne Microsoft-谢谢!很高兴了解这种方法:)
var returnValue = _context.Database
    .SqlQuery<string>("sqlServerProcedure @p0, @p1, @p2", dateBegin, dateEnd, id)
    .FirstOrDefault();