实体框架核心使用存储过程删除带有布尔返回的实体



我有一个实体,让我们把它称为"实体";,要使用存储过程删除的。";实体";实体相对复杂,有很多相关的实体——因此,我想使用存储过程来删除实体。

CREATE PROCEDURE dbo.spDeleteEntity
@EntityId int,
@ServiceResult bit output
AS
BEGIN
.... Delete logic here ...
IF @@ERROR = 0
SET @ServiceResult = 1
ELSE SET @ServiceResult = 0
END

正如您所看到的,存储过程为实体接收一个EntityId,执行我的删除逻辑,并返回一个位——在本例中是我的ServiceResult。这里CCD_ 3是"0";真"如果在执行查询时没有出现错误;"错误"/如果出现错误,则为0。现在的问题是,我希望能够从.NET Core执行这个存储过程。我最初的想法是做一些类似的事情

public bool DeleteEntity(Entity Entity)
{
return _context.Entity.FromSqlRaw<bool>("spDeleteEntity {0}", Entity.Id);
}

我认为这不起作用,因为实体框架核心不知道它应该期望什么数据类型。据我所知,EntityFrameworkCore只接受TEntity类型。所以我真正的问题是,我如何用实体框架核心调用存储过程,这样我就可以传递一个Id并返回一个bool值。

在您的情况下,您可以在过程中简单地使用RAISERROR来指示失败。;

try{
_context.Database.ExecuteSqlInterpolatedAsync($"spDeleteEntity {Entity.Id}");
return true;
}catch(...){
return false;
}

有一种方法可以使用EF Core将sql参数传入/传出原始sql命令;

var entityId = new SqlParameter("@entityId", Entity.Id);
var result = new SqlParameter("@result", SqlDbType.Bit)
{ Direction = ParameterDirection.Output };
_context.Database.ExecuteSqlRaw("EXEC @result = spDeleteEntity @entityId", entityId, result);
return (bool)result.Value;

在try-catch中调用存储过程,并添加要传递给sp的SqlParameter,如下所示:

try
{
using(var context = new SampleContext())
{
//Declare storedprocedure parameter
var Idp = new SqlParameter("@IdParam", "Idp");
//Call stored procedure(For async call use ExecuteSqlCommandAsync method) 
context.Database.ExecuteSqlCommand("EXEC spName @IdParam", Idp);
}
Return true:
}
catch
{
Return false;
}

通过这种方式,如果sp的执行出现错误,它将执行catch并返回false,否则返回true。
注意:如果在存储过程中声明raiseerror,则可以生成一条错误消息并将其发送到应用程序try-catch。有关raiserror的更多详细信息:https://learn.microsoft.com/en-us/sql/t-sql/language-elements/raiserror-transact-sql?view=sql-服务器-ver15

这是一个迟来的答案,但以下是我与EFCore 5:一起使用的解决方案

存储过程使用输出

CREATE OR ALTER   PROCEDURE [dbo].[SP_GET_RESULT]
(
@Param1 int,
@Result bit OUTPUT
)
AS
BEGIN
-- Do something
SET @Result = 1    
END
GO

然后c#调用如下:

using System.Data;
using System.Threading.Tasks;
using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore;

try
{
SqlParameter @Param1 = new SqlParameter("@Param1", oneInt);
SqlParameter @Result = new SqlParameter("@Result", SqlDbType.Bit)
{
Direction = ParameterDirection.Output,
Value = 0,
};
await this.context.Database.ExecuteSqlRawAsync(
"EXEC SP_GET_RESULT @Param1, @Result OUTPUT",
@Param1,
@Result);
return (bool)@Result.Value;
}
catch (Exception e)
{
...
}

实际上,我不确定是否需要初始化输出参数。

这可以适用于任何SQL类型的

最新更新