简体   繁体   English

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

[英]How to get return values and output values from a stored procedure with EF 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 ...

EF Repository: 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);
    }
}

I call this like:我称之为:

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

query1 does get the output pTotalRecords fine, but no return values, and the second query2 gets the return values but no output parameter. query1确实得到了 output pTotalRecords很好,但没有返回值,第二个query2得到了返回值,但没有 output 参数。

In EF 6, we used to have SqlQuery to do both actions in one command, how can I do the same in EF core?在 EF 6 中,我们曾经让SqlQuery在一个命令中执行这两个操作,我如何在 EF 核心中执行相同的操作?

UPDATED :更新

Temporarily, I run 2 query, one to get the output param and one for result set.暂时,我运行 2 个查询,一个用于获取 output 参数,一个用于结果集。

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

I did something like this :-我做了这样的事情:-

-- My stored procedure: -- 我的存储过程:

CREATE PROCEDURE p1
AS
     BEGIN            
        RETURN 29
     END
GO

C# code 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 

Hope this helps希望这可以帮助

I am working to convert some EF6 code to EF Core, and ran into this same issue.我正在努力将一些 EF6 代码转换为 EF Core,并遇到了同样的问题。 In Microsoft.EntityFrameworkCore version 2.1.0 the following use of FromSql() does return a result set and set the output parameter.在 Microsoft.EntityFrameworkCore 版本 2.1.0 中, FromSql()的以下使用确实返回结果集并设置输出参数。 You have to use .ToList() to force the proc to execute immediately, thereby returning both the results and the output param.您必须使用.ToList()强制 proc 立即执行,从而返回结果和输出参数。

This is a sample from my DbContext class:这是我的 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;
}

The stored proc returns the following entity:存储过程返回以下实体:

public class ExampleStoredProc_Result
{
    public int ID { get; set; }
    public string Name { get; set; }
}

Here's the stored proc:这是存储过程:

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

Hopefully anyone that comes across this post in the future finds this useful.希望将来遇到这篇文章的任何人都觉得这很有用。

var results = ExampleStoredProc_Results.FromSql(sqlQuery, parameters).ToList();

DbSet.FromSql Enables you to pass in a SQL command to be executed against the database to return instances of the type represented by the DbSet. DbSet.FromSql使您能够传入要对数据库执行的 SQL 命令,以返回由 DbSet 表示的类型的实例。

This answer will done the trick for me.这个答案将为我解决问题。

While trying to call a stored procedure with one input and one output parameter using ExecuteSqlCommandAsync EF Core.在尝试使用 ExecuteSqlCommandAsync EF Core 调用具有一个输入和一个输出参数的存储过程时。 I was avoiding using FromSql on the entity object.我避免在实体对象上使用 FromSql。 Below code worked great from me so just wanted to share on this old post.下面的代码对我来说效果很好,所以只想在这个旧帖子上分享。

    SqlParameter Param1 = new SqlParameter();
    Param1 .ParameterName = "@Param1";
    Param1 .SqlDbType = SqlDbType.VarChar;
    Param1 .Direction = ParameterDirection.Input;
    Param1 .Size = 50;
    Param1 .Value = "ParamValue";

    SqlParameter Param2 = new SqlParameter();
    Param2 .ParameterName = "@Param2";
    Param2 .SqlDbType = SqlDbType.VarChar;
    Param2 .Size = 2048;
    Param2 .Direction = ParameterDirection.Output;

    var sprocResponse = await _dbContext.Database.ExecuteSqlCommandAsync("[dbo].[StoredProcName]  @Param1= @Param1, @Param2 = @Param2 OUTPUT", new object[] { Param1, Param2});
    string outPutVal= urlParam.Value.ToString();

Late response, but may be useful for someone:迟到的回应,但可能对某人有用:

My stored procedure:我的存储过程:

create procedure GetSomething(@inCode varchar(5), @outValue int OUTPUT)
as
Set @outValue = 1
end

In C#,在 C# 中,

SqlParameter[] parameters =
{
   new SqlParameter("@inCode", SqlDbType.Varchar { Direction = ParameterDirection.Input, Value = "InputValue" },
   new SqlParameter("@outValue", SqlDbType.Int { Direction = ParameterDirection.Output }
}
dbContext.Database.ExecuteSqlRaw("exec GetSomething @inCode, @outValue OUTPUT", parameters);
var result - parameters[1].Value;

The keyword OUTPUT is important while calling from .net从 .net 调用时,关键字OUTPUT很重要

map into context as keyless entity map 作为无钥匙实体进入上下文

    modelBuilder
.Entity<yourentity>(
    eb =>
    {
        eb.HasNoKey();
        eb.ToView("procname");
    });

add a dbset添加一个数据库集

   public DbSet<yourentity> yourentity { get; set; }

exclude it from migrations将其从迁移中排除

  modelBuilder.Entity<yourentity>().ToTable("procname", t => t.ExcludeFromMigrations());

then in context can execute it into the mapped type然后在上下文中可以将其执行为映射类型

var values = context.yourentity.FromSqlRaw("EXECUTE dbo.procname");

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM