[英]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.