Linq 使用实体框架的事务范围中的引用键错误

Linq 使用实体框架的事务范围中的引用键错误,linq,entity-framework,asp.net-mvc-4,transactions,Linq,Entity Framework,Asp.net Mvc 4,Transactions,我使用事务作用域在多个表中使用Try-and-Catch执行插入。但是当我在事务范围内得到错误时,它也不允许我在catch中保存数据 我的代码 现在的问题是,每当我在外键约束的try块中得到错误时,我就无法插入到ErrorHandlerTable独立表中。始终获得以下异常: 有人能帮上忙吗?如下所示:- 在表ysmgr.Table2中,它有一个对的外键引用 另一张桌子。FK的工作方式是,它不能具有该值 不在被引用对象的主键列中的列 桌子 如果您有SQLServerManagementStudio

我使用事务作用域在多个表中使用Try-and-Catch执行插入。但是当我在事务范围内得到错误时,它也不允许我在catch中保存数据

我的代码

现在的问题是,每当我在外键约束的try块中得到错误时,我就无法插入到ErrorHandlerTable独立表中。始终获得以下异常:

有人能帮上忙吗?

如下所示:-

在表ysmgr.Table2中,它有一个对的外键引用 另一张桌子。FK的工作方式是,它不能具有该值 不在被引用对象的主键列中的列 桌子

如果您有SQLServerManagementStudio,请打开它并获取帮助 “表2”。查看FK所在的列,以及 它引用的表的列。你插入了一些坏数据

因此,这些步骤是:-

1.运行sp_helpconstraint


2.注意为外键返回的constraint_keys列,问题是,即使您的代码已经处理了TransactionScope,当它在ErrorHandlerTable中插入数据时,仍然会在TransactionScope中发生。所以,有些地方出了问题,你得到了一个误导性的错误

为了避免这种情况,请更改代码,以便在原始事务范围之外插入ErrorHandlerTable。为此,您可以嵌套一个新的using块,以提供一个新的、独立的TransactionScope,如下所示:

using(var ts  = new TrasanctionScope(TransactionScopeOption.RequiresNew)
还是这个

using(var ts  = new TrasanctionScope(TransactionScopeOption.Suppress)
第一个选项只是创建一个新事务,与原始事务无关。但是,如果您的insert看起来是一个原子操作,那么您也可以使用第二个选项,它创建了一个新的独立的无事务作用域

通过这种方式,您可以确保插入ErrorHandlerTable时不会干扰原始事务范围

请参见以下文档:


我认为这将帮助您恢复表中的操作,请尝试使用以下内容

   using (var transaction = new TransactionScope())
   {
     try
     {
         //Insert in Table1
         //Insert in Table2
         //Insert in Table3

         transaction.Complete();    
         transaction.Dispose();    
     }
     catch(Exception ex)
     {
        transaction.Dispose();  

          //what i have changed
          context.Table1 Table1Object = new YoSafari.Migration.EntityFramework.Table1(); //Create New Object of the table in which u want to insert i.e. Table1 or Table2 etc..
           using (var context = new ContextClass())
           {
              context.Entry(Table1Object).State = EntityState.Unchanged;                  
              //Insert in ErrorHandlerTable (Independent Table i.e. Table1 or Table2 etc..)
              context.SaveChanges();
           }
     }
  }
它将创建表的新对象,该对象将更改操作,并允许您将记录插入到ErrorHandlerTable中


如果您仍然面临任何问题,请告诉我。

您的错误表中是否有PkId作为外键@crackerPkId在表1中是主键,在表2中是外键,所以我发送的数据不在表1中。这就是为什么它给了我错误。但是为什么我不能在ErroHandlerTable中存储异常,因为它不包含任何关系。您的catch语句是否捕获异常@您是先处理还是先添加?因为我在您的代码示例@Cracker中看不到任何插入代码,我先提交事务,然后再处理事务,但是在try块中生成的错误不允许我在cath块中插入数据,也不允许我在JotaBe中插入数据,让我尝试一下。这是不正确的。如果TS被处理,它将不再有效。dispose之后的代码运行起来就好像从来没有TS一样。@GertArnold是否有任何地方可以让我看到它是如何工作的?还是我必须直接看源代码?TransactionScope引用,即使调用了Dispose,相关对象在该点仍然可用。所以我认为发生最后一个操作的环境事务仍然是相同的,因此该操作发生在相同的范围内。如果释放TransactionScope,允许在事务外部执行以下操作,会发生什么情况?谢谢你的评论!!哦,这与TS没有特别的关系。这只是使用的方式。毫无疑问,正如您所知,using在大括号定义的using范围的末尾处理对象。但是,如果出于某种原因,该对象被较早地处理,则大致与将闭合大括号移动到该点相同。它取决于对象的Dispose实现,当对象被Dispose时会发生什么。在TS的情况下,如果未调用Complete,则为回滚。如果这是一个实体,如果引用的表在同一个dbsetIf中,则不需要相关表的事务作用域。如果在表1中插入失败,如何插入引用它的记录?这与事务范围无关,不管发生什么异常。但无论如何,只需删除所有事务;语句。是的,我不能在引用它的表中插入,但我想插入错误,该错误是在将数据插入一个名为ErrorHandlerTable的独立表中时产生的,但它仍然给我插入数据时产生的错误。所以,在这种情况下我应该做的是,如果您一直遇到外键冲突,那么请确保插入没有外键引用的内容。是什么让您认为可以通过处理事务作用域来修复异常的?我在处理所有表时使用外键
LINQ那么有没有选择不使用外键引用!!我之所以使用事务作用域,是因为我需要在多个表中插入数据,使用每个主键作为其他表的外键,并且我希望在插入数据时出现任何错误时回滚事务。由于我想跟踪事务执行期间发生的错误。感谢您回答@X-Developer,让我也尝试一下
using(var ts  = new TrasanctionScope(TransactionScopeOption.Suppress)
   using (var transaction = new TransactionScope())
   {
     try
     {
         //Insert in Table1
         //Insert in Table2
         //Insert in Table3

         transaction.Complete();    
         transaction.Dispose();    
     }
     catch(Exception ex)
     {
        transaction.Dispose();  

          //what i have changed
          context.Table1 Table1Object = new YoSafari.Migration.EntityFramework.Table1(); //Create New Object of the table in which u want to insert i.e. Table1 or Table2 etc..
           using (var context = new ContextClass())
           {
              context.Entry(Table1Object).State = EntityState.Unchanged;                  
              //Insert in ErrorHandlerTable (Independent Table i.e. Table1 or Table2 etc..)
              context.SaveChanges();
           }
     }
  }