【问题标题】:Problems executing SQL Server Stored Procedures from EFCore从 EFCore 执行 SQL Server 存储过程时出现问题
【发布时间】:2021-06-14 23:29:24
【问题描述】:

我有一个包含多个表的数据库,并且我准备了一个存储过程(基本上由 delete * from ... 语句组成)来从这些表中删除行。当我从 SQL Server Management Studio 运行存储过程时,它工作得很好。 现在,我想从我的 C# 应用程序中执行相同的存储过程。我使用下面的代码来做到这一点:

using (var context = new DBContext())
{
    var param = new SqlParameter[] {...}; //create parameters here
    //trigger the stored procedure for deletion from the first table here
    context.Database.ExecuteSqlRaw("[dbo].[delete_first] @id,@date", param);
                        
    //trigger the stored procedure for deletion from the hts_clients table here
    context.Database.ExecuteSqlRaw("[dbo].[delete_second] @id,@date", param);
}

执行时,第一次调用似乎工作正常。但是,第二个总是抛出异常并显示以下消息:

EXECUTE 之后的事务计数表明 BEGIN 和 COMMIT 语句的数量不匹配。先前计数 = 0,当前计数 = 1。EXECUTE 之后的事务计数表示 BEGIN 和 COMMIT 语句的数量不匹配。先前计数 = 0,当前计数 = 1

(注意:是的,异常信息出现的正是这个样子。我没有粘贴两次。)

但是,我绝对没有在存储过程的主体中使用任何事务,即我在其中任何一个地方都没有 Begin Transaction/Commit Transaction/Rollback Transactions 语句,我也没有将调用包装在来自 EFCore 的事务中(从上面的代码段可以看出)。谁能告诉我为什么会这样? 提前致谢。

【问题讨论】:

  • 其中大多数 ORM 和 EF 都在内部使用事务。遗憾的是,我对错误一无所知。
  • 也许在第二次调用时使用不同的参数集?
  • 您是否尝试过使用相同的参数手动执行您的 sp?它可能会引发错误。你的 sp 有 try/catch 块吗?
  • 表上有触发器吗?也许尝试只从应用程序执行第一个并让第一个 proc exec 执行第二个......?
  • 必须是存储过程中的东西。 EF 甚至不在这里启动事务。

标签: c# sql-server stored-procedures .net-core entity-framework-core


【解决方案1】:

执行Sql 后 dbContext 没有自动刷新。您必须重新加载已更改的条目。

尝试使用这个:

 context.Database.ExecuteSqlRaw("[dbo].[delete_first] @id,@date", param);
  _context.Entry(...deletionClass...  ).Reload();
 
    context.Database.ExecuteSqlRaw("[dbo].[delete_second] @id,@date", param);

//and maybe if you need  you can try it again
 _context.Entry(...deletionClass...  ).Reload();

但在您的情况下,为第二个存储过程创建新的 DbContext 可能更容易。

using (var context1 = new DBContext())
{
    var param = new SqlParameter[] {...}; //create parameters here
    //trigger the stored procedure for deletion from the first table here
    context1.Database.ExecuteSqlRaw("[dbo].[delete_first] @id,@date", param);
 }
 using (var context2 = new DBContext())
{
var param = new SqlParameter[] {...}; //create parameters here                      
    //trigger the stored procedure for deletion from the hts_clients table here
    context2.Database.ExecuteSqlRaw("[dbo].[delete_second] @id,@date", param);
}


【讨论】:

    猜你喜欢
    • 2021-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-31
    • 2011-11-07
    • 1970-01-01
    • 1970-01-01
    • 2023-03-17
    相关资源
    最近更新 更多