与 REFERENCE 约束冲突。如何解决这个问题?

Conflicted with the REFERENCE constraint. How to solve this?

我捕获了这个 GenericADOException 异常,但是当我执行 genRep.Update(userW) 时又出现了一些意外的异常。我该如何解决这个问题?这是我的代码:

public ActionResult DeleteUser(long? UserID)
{
    GenericRepositoryV2 genRep ;
    if (!SecurityService.IsLoggedIn(Session))
    {
        return SecurityService.LoginAndRedirect(Request);
    }

    try
    {
        genRep = new GenericRepositoryV2();
        genRep.StartTransaction();
        User user = genRep.GetById<User>(UserID);
        if (user == null)
        {
            found = false;
        }
        else
        {
            UserWrapper userW = genRep.GetByIdUser(UserID);                    
            genRep.Remove<User>(userW);
            genRep.EndTransaction();            
        }
    }
    catch (GenericADOException gae)
    {
        if (gae.InnerException.Message.IndexOf("REFERENCE constraint") != -1)
        {
            genRep = new GenericRepositoryV2();
            genRep.StartTransaction();
            UserWrapper userW = genRep.GetByIdUser(Convert.ToInt64(UserID));
            userW.Status = UserStatus.PendingDelete;
            genRep.Update(userW);
            genRep.Flush();
            genRep.EndTransaction();
        }

        //_log.Error("An error has occured while deleting the user.");
    }
    catch (Exception e)
    {
        _log.Error("Unexpected, unhandled exception: ", e);
    }
    return RedirectToAction(viewAllUsers);
}

希望有人帮助我! 提前谢谢你

更新 1:

异常:

NHibernate.Exceptions.GenericADOException was caught
  HResult=-2146232832
  Message=could not execute batch command.[SQL: SQL not available]
  Source=NHibernate
  SqlString=SQL not available
  StackTrace:
       at NHibernate.AdoNet.SqlClientBatchingBatcher.DoExecuteBatch(IDbCommand ps)
       at NHibernate.AdoNet.AbstractBatcher.ExecuteBatchWithTiming(IDbCommand ps)
       at NHibernate.AdoNet.AbstractBatcher.ExecuteBatch()
       at NHibernate.Engine.ActionQueue.ExecuteActions(IList list)
       at NHibernate.Engine.ActionQueue.ExecuteActions()
       at NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource session)
       at NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent event)
       at NHibernate.Impl.SessionImpl.Flush()
       at NHibernate.Transaction.AdoTransaction.Commit()
       at OmanERP.Persistence.GenericRepositoryV2.EndTransaction() in e:\OmanERP\OmanERP\Persistence\GenericRepositoryV2.cs:line 583
       at OmanERP.Controllers.UserController.DeleteUser(Nullable`1 UserID) in e:\OmanERP\OmanERP\Controllers\UserController.cs:line 144
  InnerException: System.Data.SqlClient.SqlException
       HResult=-2146232060
       Message=The DELETE statement conflicted with the REFERENCE constraint "FK48A70817829118FC". The conflict occurred in database "OmanERP_Harpreet", table "dbo.Invoices", column 'GeneratedByID'.
The statement has been terminated.
       Source=.Net SqlClient Data Provider
       ErrorCode=-2146232060
       Class=16
       LineNumber=1
       Number=547
       Procedure=""
       Server=192.168.1.20
       State=0
       StackTrace:
            at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
            at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
            at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
            at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
            at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
            at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite)
            at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite)
            at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite)
            at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
            at System.Data.SqlClient.SqlCommand.ExecuteBatchRPCCommand()
            at System.Data.SqlClient.SqlCommandSet.ExecuteNonQuery()
            at NHibernate.AdoNet.SqlClientSqlCommandSet.ExecuteNonQuery()
            at NHibernate.AdoNet.SqlClientBatchingBatcher.DoExecuteBatch(IDbCommand ps)
       InnerException:

根据该错误判断,您的存储库正试图从其 table 中删除用户,但该用户在另一个 table (dbo.Invoices) 中被引用。

因此,当您尝试删除主键在另一个 table 中作为外键引用的记录时,您看到了外键约束错误。

发票上的 GeneratedById table 是否可以为空?如果是,则在 Nhibernate 中设置级联规则,以便在删除父实体用户时清空 GeneratedById。

但是,一种常见的方法是从不完全删除任何记录,而是在该实体上设置一个字段以表示其已删除,例如名为 IsDeleted(位)或 DeletedOn(日期时间)的字段并隐藏记录"soft" 从 UI 删除。

谢谢大家给我的建议

我终于找到了我自己的解决方案 problem.I 只需创建一个 Rollback() 事务方法,即 "genRep.RollbackTransaction()" 并创建一个新的 session()。因为 Flush() 之后的 Nhibernate 刷新会话。

回滚方法:

 public void RollbackTransaction()
    {
        if (null != this._trans && this._trans.IsActive)
        {
            this._trans.Rollback();
        }
    }

这是我的代码:

 catch (GenericADOException gae)
            {

                if (gae.InnerException.Message.IndexOf(referenceConstraint) != -1)
                {
                    genRep.RollbackTransaction();
                    genRep.NewSession();
                    UserWrapper userW = genRep.GetByIdUser(Convert.ToInt64(UserID));
                    userW.Status = UserStatus.PendingDelete;
                    genRep.Update(userW);

                 }


            }
            catch (Exception e)
            {
                _log.Error("Unexpected, unhandled exception: ", e);
            }
        }