【问题标题】:How to get the Update SQL statement out of NHibernate exception?如何从 NHibernate 异常中获取更新 SQL 语句?
【发布时间】:2014-11-04 09:11:19
【问题描述】:

我正在处理一些遗留代码,这些代码在将聚合保存到数据库时会中断。 SQL 服务器的错误是著名的“SqlDateTime 溢出”。必须在 1753 年 1 月 1 日之间...等'

我的问题是:是否可以询问 NHibernate 框架执行了什么 SQL 导致了这个异常?这样我将有一个简单的方法来找出我必须找到问题的 POCO。

是否可以将侦听器附加到 NHibernate IDbCommand 或其他东西?

以下此类异常的示例堆栈跟踪:

SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM. StackTrace:    at System.Data.SqlClient.TdsParser.TdsExecuteRPC(_SqlRPC[] rpcArray, Int32 timeout, Boolean inSchema, SqlNotificationRequest notificationRequest, TdsParserStateObject stateObj, Boolean isCommandProc, Boolean sync, TaskCompletionSource`1 completion, Int32 startRpc, Int32 startParam)
   at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds)
   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.ExecuteNonQuery()
   at System.Data.SqlClient.SqlCommandSet.ExecuteNonQuery()
   at NHibernate.AdoNet.SqlClientBatchingBatcher.DoExecuteBatch(IDbCommand ps)
   at NHibernate.AdoNet.AbstractBatcher.ExecuteBatchWithTiming(IDbCommand ps)
   at NHibernate.AdoNet.AbstractBatcher.ExecuteBatch()
   at NHibernate.AdoNet.AbstractBatcher.PrepareCommand(CommandType type, SqlString sql, SqlType[] parameterTypes)
   at NHibernate.Persister.Entity.AbstractEntityPersister.Update(Object id, Object[] fields, Object[] oldFields, Object rowId, Boolean[] includeProperty, Int32 j, Object oldVersion, Object obj, SqlCommandInfo sql, ISessionImplementor session)
   at NHibernate.Persister.Entity.AbstractEntityPersister.UpdateOrInsert(Object id, Object[] fields, Object[] oldFields, Object rowId, Boolean[] includeProperty, Int32 j, Object oldVersion, Object obj, SqlCommandInfo sql, ISessionImplementor session)
   at NHibernate.Persister.Entity.AbstractEntityPersister.Update(Object id, Object[] fields, Int32[] dirtyFields, Boolean hasDirtyCollection, Object[] oldFields, Object oldVersion, Object obj, Object rowId, ISessionImplementor session)
   at NHibernate.Action.EntityUpdateAction.Execute()
   at NHibernate.Engine.ActionQueue.Execute(IExecutable executable)
   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 Haddock.Business.Services.CommonRepositoryBase`3.SaveOrUpdate(TRootAggregate rootAggregate) in d:\Builds\4\Haddock\Haddock.Releases.P44-2014.SL\Sources\Business\Haddock.Business.Services\CommonRepositoryBase.cs:line 140
...

我正在考虑向 CommonRepositoryBase 类添加一些额外的检查代码,该类在整个项目中都使用。

代码如下,其实很好理解:

ISession session = GetSession();
        using (ITransaction transaction = session.BeginTransaction())
        {
            try
            {
                session.SaveOrUpdate(rootAggregate);
                transaction.Commit(); // does a flush internally
            }
            catch (Exception)
            {
                transaction.Rollback();
                throw;
            }
        }

所以,我的目标是在该 Catch 块中添加一些代码,以检查正在使用的会话和事务,并使用 NHibernate 想要执行的 SQL 语句扩展该异常。

【问题讨论】:

    标签: c# sql-server nhibernate


    【解决方案1】:

    您可以在 SQL Server Management Studio 中使用 SQL Server Profiler 来跟踪正在数据库上运行的查询。

    在复制错误之前启动分析器,您可以从那里看到执行的查询。

    除了查询转储之外,您还可以查看有关已执行查询的更多详细信息,例如执行时间等。

    【讨论】:

    • 感谢您的回答,没错,我们有时会在开发/登台系统上使用 SQL Profiler。但是.. 当然,这个问题似乎只发生在我们无法运行 SQL Profiler 的实时系统上。我认为它可能是对系统/休眠的一个很好的补充,如果它告诉你它试图在不运行探查器的情况下自行执行什么 sql 语句;-)
    猜你喜欢
    • 2014-11-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-06
    • 2021-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-17
    相关资源
    最近更新 更多