如何使用EF Core从存储过程中获取返回值和输出值?

nam*_* vo 6 c# asp.net-mvc entity-framework entity-framework-core asp.net-core

ALTER PROCEDURE [dbo].[SearchMovies]
    --@Year     int = null,
    @CategoryIds varchar(50) = null,
    @Keywords nvarchar(4000) = null,
    @PageIndex int = 1, 
    @PageSize int = 2147483644,
    @TotalRecords int = null OUTPUT
As ...
Run Code Online (Sandbox Code Playgroud)

EF存储库:

 public class EFRepository<T> : IRepository<T> where T : BaseEntity
{
    private readonly ApplicationDbContext _ctx;
    private  DbSet<T> entities;
    string errorMessage = string.Empty;

    public EFRepository(ApplicationDbContext context)
    {
        this._ctx = context;
        entities = context.Set<T>();
    }     
   ...

    public IQueryable<T> ExecuteStoredProcedureList(string commandText, params object[] parameters)
    {          
        _ctx.Database.ExecuteSqlCommand(commandText, parameters);
        return entities.FromSql(commandText, parameters);
    }
}
Run Code Online (Sandbox Code Playgroud)

我称之为:

var pCategoryIds = new SqlParameter()
            {
                ParameterName = "@CategoryIds",
                Value = commaSeparatedCategoryIds,
                DbType = DbType.String
            };
var pKeywords = new SqlParameter()
            {
                ParameterName = "@Keywords",
                DbType = DbType.String,
                Value = name
            };
var pPageIndex = new SqlParameter()
            {
                ParameterName = "@PageIndex",
                DbType = DbType.Int32,
                Value = pageIndex
            };
var pPageSize = new SqlParameter()
            {
                ParameterName = "@PageSize",
                DbType = DbType.Int32,
                Value = pageSize
            };

var pTotalRecords = new SqlParameter();
pTotalRecords.ParameterName = "@TotalRecords";
pTotalRecords.Direction = ParameterDirection.Output;
pTotalRecords.DbType = DbType.Int32;

var query1 = _ctx.Database.ExecuteSqlCommand("dbo.[SearchMovies] " +
                "@CategoryIds, @Keywords, @PageIndex, @PageSize, @TotalRecords OUTPUT", 
                pCategoryIds, pKeywords, pPageIndex, pPageSize, pTotalRecords);

var query2 = _ctx.Set<MovieItem>.FromSql("dbo.[SearchMovies] " +
                    "@CategoryIds, @Keywords, @PageIndex, @PageSize, @TotalRecords OUTPUT",
                    pCategoryIds, pKeywords, pPageIndex, pPageSize, pTotalRecords);
Run Code Online (Sandbox Code Playgroud)

query1确实输出pTotalRecords正常,但没有返回值,第二个query2获取返回值但没有输出参数.

在EF 6中,我们以前必须SqlQuery在一个命令中执行这两个操作,如何在EF核心中执行相同的操作?

更新:

暂时,我运行2个查询,一个用于获取输出参数,另一个用于结果集.

 public IQueryable<T> ExecuteStoredProcedureList(string commandText, params object[] parameters)
    {          
        _ctx.Database.ExecuteSqlCommand(commandText, parameters);
        return entities.FromSql(commandText, parameters);
    }
Run Code Online (Sandbox Code Playgroud)

kep*_*ung 11

我做了这样的事情:-

-我的存储过程:

CREATE PROCEDURE p1
AS
     BEGIN            
        RETURN 29
     END
GO
Run Code Online (Sandbox Code Playgroud)

C#代码

SqlParameter[] @params = 
{
   new SqlParameter("@returnVal", SqlDbType.Int) {Direction = ParameterDirection.Output}
 };   


_stagingContext.Database.ExecuteSqlCommand("exec @returnVal=" + storedProcName, @params);

var result = @params[0].Value; //result is 29 
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助

  • 您能否解释一下,为什么选择 ParameterDirection.Output 而不是 ParameterDirection.ReturnValue?p1 返回 29 作为“简单”返回值,而不是作为输出参数。 (3认同)
  • 我的问题是如何返回数据集和输出值,而不仅仅是输出变量 (2认同)

tbe*_*s42 6

我正在努力将一些 EF6 代码转换为 EF Core,但遇到了同样的问题。在 Microsoft.EntityFrameworkCore 2.1.0 版中,以下使用FromSql()确实返回结果集并设置输出参数。您必须使用.ToList()强制proc 立即执行,从而返回结果和输出参数。

这是来自我的 DbContext 类的示例:

private DbQuery<ExampleStoredProc_Result> ExampleStoredProc_Results { get; set; }
public IEnumerable<ExampleStoredProc_Result> RunExampleStoredProc(int firstId, out bool outputBit)
{
    var outputBitParameter = new SqlParameter
    {
        ParameterName = "outputBit",
        SqlDbType = SqlDbType.Bit,
        Direction = ParameterDirection.Output
    };

    SqlParameter[] parameters =
    {
        new SqlParameter("firstId", firstId),
        outputBitParameter
    };

    // Need to do a ToList to get the query to execute immediately 
    // so that we can get both the results and the output parameter.
    string sqlQuery = "Exec [ExampleStoredProc] @firstId, @outputBit OUTPUT";
    var results = ExampleStoredProc_Results.FromSql(sqlQuery, parameters).ToList();

    outputBit = outputBitParameter.Value as bool? ?? default(bool);

    return results;
}
Run Code Online (Sandbox Code Playgroud)

存储过程返回以下实体:

public class ExampleStoredProc_Result
{
    public int ID { get; set; }
    public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

这是存储的过程:

CREATE PROCEDURE ExampleStoredProc 
    @firstId int = 0,
    @outputBit BIT OUTPUT
AS
BEGIN
    SET NOCOUNT ON;

    SET @outputBit = 1;

    SELECT @firstId AS [ID], 'first' AS [NAME]
    UNION ALL
    SELECT @firstId + 1 AS [ID], 'second' AS [NAME]
END
GO
Run Code Online (Sandbox Code Playgroud)

希望将来遇到这篇文章的任何人都会发现这很有用。