From: <aye...@us...> - 2009-05-08 02:22:33
|
Revision: 4265 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4265&view=rev Author: ayenderahien Date: 2009-05-08 01:45:53 +0000 (Fri, 08 May 2009) Log Message: ----------- Adding session id notion that goes into the NDC context Please note that this feature is mostly required for automated tools that need to correlate different log messages from the same session (NHProf) There is no change in the log output if you don't explicitly request is ( using property{sessionId} ) Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Engine/ISessionImplementor.cs trunk/nhibernate/src/NHibernate/Impl/AbstractSessionImpl.cs trunk/nhibernate/src/NHibernate/Impl/MultiCriteriaImpl.cs trunk/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs trunk/nhibernate/src/NHibernate/Impl/SessionImpl.cs trunk/nhibernate/src/NHibernate/Impl/StatelessSessionImpl.cs trunk/nhibernate/src/NHibernate/NHibernate.csproj trunk/nhibernate/src/NHibernate/Transaction/AdoTransaction.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate/Impl/SessionIdLoggingContext.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/Logs/ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/Logs/LogsFixture.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/Logs/Mappings.hbm.xml trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/Logs/Person.cs Modified: trunk/nhibernate/src/NHibernate/Engine/ISessionImplementor.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Engine/ISessionImplementor.cs 2009-05-08 01:26:08 UTC (rev 4264) +++ trunk/nhibernate/src/NHibernate/Engine/ISessionImplementor.cs 2009-05-08 01:45:53 UTC (rev 4265) @@ -1,3 +1,4 @@ +using System; using System.Collections; using System.Collections.Generic; using System.Data; @@ -287,5 +288,7 @@ FutureCriteriaBatch FutureCriteriaBatch { get; } FutureQueryBatch FutureQueryBatch { get; } + + Guid SessionId { get; } } } Modified: trunk/nhibernate/src/NHibernate/Impl/AbstractSessionImpl.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/AbstractSessionImpl.cs 2009-05-08 01:26:08 UTC (rev 4264) +++ trunk/nhibernate/src/NHibernate/Impl/AbstractSessionImpl.cs 2009-05-08 01:45:53 UTC (rev 4265) @@ -25,6 +25,8 @@ { [NonSerialized] private ISessionFactoryImplementor factory; + + protected readonly Guid sessionId = Guid.NewGuid(); private bool closed; private System.Transactions.Transaction ambientTransation; private bool isAlreadyDisposed; @@ -32,6 +34,11 @@ private static readonly ILog logger = LogManager.GetLogger(typeof (AbstractSessionImpl)); + public Guid SessionId + { + get { return sessionId; } + } + protected bool TakingPartInDtcTransaction { get @@ -51,7 +58,10 @@ public void Initialize() { - CheckAndUpdateSessionStatus(); + using(new SessionIdLoggingContext(sessionId)) + { + CheckAndUpdateSessionStatus(); + } } public abstract void InitializeCollection(IPersistentCollection collection, bool writing); @@ -98,16 +108,20 @@ public virtual IQuery GetNamedSQLQuery(string name) { - CheckAndUpdateSessionStatus(); - NamedSQLQueryDefinition nsqlqd = factory.GetNamedSQLQuery(name); - if (nsqlqd == null) - { - throw new MappingException("Named SQL query not known: " + name); - } - IQuery query = new SqlQueryImpl(nsqlqd, this, factory.QueryPlanCache.GetSQLParameterMetadata(nsqlqd.QueryString)); - query.SetComment("named native SQL query " + name); - InitQuery(query, nsqlqd); - return query; + using (new SessionIdLoggingContext(sessionId)) + { + CheckAndUpdateSessionStatus(); + NamedSQLQueryDefinition nsqlqd = factory.GetNamedSQLQuery(name); + if (nsqlqd == null) + { + throw new MappingException("Named SQL query not known: " + name); + } + IQuery query = new SqlQueryImpl(nsqlqd, this, + factory.QueryPlanCache.GetSQLParameterMetadata(nsqlqd.QueryString)); + query.SetComment("named native SQL query " + name); + InitQuery(query, nsqlqd); + return query; + } } public abstract IQueryTranslator[] GetQueries(string query, bool scalar); @@ -133,28 +147,33 @@ public virtual IQuery GetNamedQuery(string queryName) { - CheckAndUpdateSessionStatus(); - NamedQueryDefinition nqd = factory.GetNamedQuery(queryName); - IQuery query; - if (nqd != null) - { - string queryString = nqd.QueryString; - query = new QueryImpl(queryString, nqd.FlushMode, this, GetHQLQueryPlan(queryString, false).ParameterMetadata); - query.SetComment("named HQL query " + queryName); - } - else - { - NamedSQLQueryDefinition nsqlqd = factory.GetNamedSQLQuery(queryName); - if (nsqlqd == null) - { - throw new MappingException("Named query not known: " + queryName); - } - query = new SqlQueryImpl(nsqlqd, this, factory.QueryPlanCache.GetSQLParameterMetadata(nsqlqd.QueryString)); - query.SetComment("named native SQL query " + queryName); - nqd = nsqlqd; - } - InitQuery(query, nqd); - return query; + using (new SessionIdLoggingContext(sessionId)) + { + CheckAndUpdateSessionStatus(); + NamedQueryDefinition nqd = factory.GetNamedQuery(queryName); + IQuery query; + if (nqd != null) + { + string queryString = nqd.QueryString; + query = new QueryImpl(queryString, nqd.FlushMode, this, + GetHQLQueryPlan(queryString, false).ParameterMetadata); + query.SetComment("named HQL query " + queryName); + } + else + { + NamedSQLQueryDefinition nsqlqd = factory.GetNamedSQLQuery(queryName); + if (nsqlqd == null) + { + throw new MappingException("Named query not known: " + queryName); + } + query = new SqlQueryImpl(nsqlqd, this, + factory.QueryPlanCache.GetSQLParameterMetadata(nsqlqd.QueryString)); + query.SetComment("named native SQL query " + queryName); + nqd = nsqlqd; + } + InitQuery(query, nqd); + return query; + } } public bool IsClosed @@ -164,8 +183,11 @@ protected internal virtual void CheckAndUpdateSessionStatus() { - ErrorIfClosed(); - EnlistInAmbientTransactionIfNeeded(); + using (new SessionIdLoggingContext(sessionId)) + { + ErrorIfClosed(); + EnlistInAmbientTransactionIfNeeded(); + } } protected internal virtual void ErrorIfClosed() @@ -204,136 +226,172 @@ private void InitQuery(IQuery query, NamedQueryDefinition nqd) { - query.SetCacheable(nqd.IsCacheable); - query.SetCacheRegion(nqd.CacheRegion); - if (nqd.Timeout != -1) - { - query.SetTimeout(nqd.Timeout); - } - if (nqd.FetchSize != -1) - { - query.SetFetchSize(nqd.FetchSize); - } - if (nqd.CacheMode.HasValue) - query.SetCacheMode(nqd.CacheMode.Value); + using (new SessionIdLoggingContext(sessionId)) + { + query.SetCacheable(nqd.IsCacheable); + query.SetCacheRegion(nqd.CacheRegion); + if (nqd.Timeout != -1) + { + query.SetTimeout(nqd.Timeout); + } + if (nqd.FetchSize != -1) + { + query.SetFetchSize(nqd.FetchSize); + } + if (nqd.CacheMode.HasValue) + query.SetCacheMode(nqd.CacheMode.Value); - query.SetReadOnly(nqd.IsReadOnly); - if (nqd.Comment != null) - { - query.SetComment(nqd.Comment); - } - query.SetFlushMode(nqd.FlushMode); + query.SetReadOnly(nqd.IsReadOnly); + if (nqd.Comment != null) + { + query.SetComment(nqd.Comment); + } + query.SetFlushMode(nqd.FlushMode); + } } public virtual IQuery CreateQuery(string queryString) { - CheckAndUpdateSessionStatus(); - QueryImpl query = new QueryImpl(queryString, this, GetHQLQueryPlan(queryString, false).ParameterMetadata); - query.SetComment(queryString); - return query; + using (new SessionIdLoggingContext(sessionId)) + { + CheckAndUpdateSessionStatus(); + QueryImpl query = new QueryImpl(queryString, this, GetHQLQueryPlan(queryString, false).ParameterMetadata); + query.SetComment(queryString); + return query; + } } public virtual ISQLQuery CreateSQLQuery(string sql) { - CheckAndUpdateSessionStatus(); - SqlQueryImpl query = new SqlQueryImpl(sql, this, factory.QueryPlanCache.GetSQLParameterMetadata(sql)); - query.SetComment("dynamic native SQL query"); - return query; + using (new SessionIdLoggingContext(sessionId)) + { + CheckAndUpdateSessionStatus(); + SqlQueryImpl query = new SqlQueryImpl(sql, this, factory.QueryPlanCache.GetSQLParameterMetadata(sql)); + query.SetComment("dynamic native SQL query"); + return query; + } } protected internal virtual HQLQueryPlan GetHQLQueryPlan(string query, bool shallow) { - return factory.QueryPlanCache.GetHQLQueryPlan(query, shallow, EnabledFilters); + using (new SessionIdLoggingContext(sessionId)) + { + return factory.QueryPlanCache.GetHQLQueryPlan(query, shallow, EnabledFilters); + } } protected internal virtual NativeSQLQueryPlan GetNativeSQLQueryPlan(NativeSQLQuerySpecification spec) { - return factory.QueryPlanCache.GetNativeSQLQueryPlan(spec); + using (new SessionIdLoggingContext(sessionId)) + { + return factory.QueryPlanCache.GetNativeSQLQueryPlan(spec); + } } protected ADOException Convert(Exception sqlException, string message) { - return ADOExceptionHelper.Convert(factory.SQLExceptionConverter, sqlException, message); + using (new SessionIdLoggingContext(sessionId)) + { + return ADOExceptionHelper.Convert(factory.SQLExceptionConverter, sqlException, message); + } } protected void AfterOperation(bool success) { - if (!ConnectionManager.IsInActiveTransaction) - { - ConnectionManager.AfterNonTransactionalQuery(success); - } + using (new SessionIdLoggingContext(sessionId)) + { + if (!ConnectionManager.IsInActiveTransaction) + { + ConnectionManager.AfterNonTransactionalQuery(success); + } + } } #region IEnlistmentNotification Members void IEnlistmentNotification.Prepare(PreparingEnlistment preparingEnlistment) { - try - { - using(var tx = new TransactionScope(ambientTransation)) - { - BeforeTransactionCompletion(null); - if (FlushMode != FlushMode.Never) + using (new SessionIdLoggingContext(sessionId)) + { + try + { + using (var tx = new TransactionScope(ambientTransation)) { - using (ConnectionManager.FlushingFromDtcTransaction) - Flush(); + BeforeTransactionCompletion(null); + if (FlushMode != FlushMode.Never) + { + using (ConnectionManager.FlushingFromDtcTransaction) + Flush(); + } + logger.Debug("prepared for DTC transaction"); + + tx.Complete(); } - logger.Debug("prepared for DTC transaction"); + preparingEnlistment.Prepared(); + } + catch (Exception exception) + { + logger.Error("DTC transaction prepre phase failed", exception); + preparingEnlistment.ForceRollback(exception); - tx.Complete(); - } - preparingEnlistment.Prepared(); - } - catch (Exception exception) - { - logger.Error("DTC transaction prepre phase failed", exception); - preparingEnlistment.ForceRollback(exception); - - } + } + } } void IEnlistmentNotification.Commit(Enlistment enlistment) { - logger.Debug("committing DTC transaction"); - // we have nothing to do here, since it is the actual - // DB connection that will commit the transaction - enlistment.Done(); + using (new SessionIdLoggingContext(sessionId)) + { + logger.Debug("committing DTC transaction"); + // we have nothing to do here, since it is the actual + // DB connection that will commit the transaction + enlistment.Done(); + } } void IEnlistmentNotification.Rollback(Enlistment enlistment) { - AfterTransactionCompletion(false, null); - logger.Debug("rolled back DTC transaction"); - enlistment.Done(); + using (new SessionIdLoggingContext(sessionId)) + { + AfterTransactionCompletion(false, null); + logger.Debug("rolled back DTC transaction"); + enlistment.Done(); + } } void IEnlistmentNotification.InDoubt(Enlistment enlistment) { - AfterTransactionCompletion(false, null); - logger.Debug("DTC transaction is in doubt"); - enlistment.Done(); + using (new SessionIdLoggingContext(sessionId)) + { + AfterTransactionCompletion(false, null); + logger.Debug("DTC transaction is in doubt"); + enlistment.Done(); + } } - protected void EnlistInAmbientTransactionIfNeeded() - { - if(ambientTransation != null) - return; - if (System.Transactions.Transaction.Current==null) - return; - ambientTransation = System.Transactions.Transaction.Current.Clone(); - logger.DebugFormat("enlisted into DTC transaction: {0}", ambientTransation.IsolationLevel); - AfterTransactionBegin(null); - ambientTransation.TransactionCompleted += delegate(object sender, TransactionEventArgs e) - { - bool wasSuccessful = e.Transaction.TransactionInformation.Status == TransactionStatus.Committed; - AfterTransactionCompletion(wasSuccessful, null); - if (shouldCloseSessionOnDtcTransactionCompleted) - Dispose(true); - }; - ambientTransation.EnlistVolatile(this, EnlistmentOptions.EnlistDuringPrepareRequired); - } + protected void EnlistInAmbientTransactionIfNeeded() + { + using (new SessionIdLoggingContext(sessionId)) + { + if (ambientTransation != null) + return; + if (System.Transactions.Transaction.Current == null) + return; + ambientTransation = System.Transactions.Transaction.Current.Clone(); + logger.DebugFormat("enlisted into DTC transaction: {0}", ambientTransation.IsolationLevel); + AfterTransactionBegin(null); + ambientTransation.TransactionCompleted += delegate(object sender, TransactionEventArgs e) + { + bool wasSuccessful = e.Transaction.TransactionInformation.Status == TransactionStatus.Committed; + AfterTransactionCompletion(wasSuccessful, null); + if (shouldCloseSessionOnDtcTransactionCompleted) + Dispose(true); + }; + ambientTransation.EnlistVolatile(this, EnlistmentOptions.EnlistDuringPrepareRequired); + } + } - protected abstract void Dispose(bool disposing); + protected abstract void Dispose(bool disposing); #endregion } Modified: trunk/nhibernate/src/NHibernate/Impl/MultiCriteriaImpl.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/MultiCriteriaImpl.cs 2009-05-08 01:26:08 UTC (rev 4264) +++ trunk/nhibernate/src/NHibernate/Impl/MultiCriteriaImpl.cs 2009-05-08 01:45:53 UTC (rev 4265) @@ -65,30 +65,33 @@ public IList List() { - bool cacheable = session.Factory.Settings.IsQueryCacheEnabled && isCacheable; + using (new SessionIdLoggingContext(session.SessionId)) + { + bool cacheable = session.Factory.Settings.IsQueryCacheEnabled && isCacheable; - CreateCriteriaLoaders(); - CombineCriteriaQueries(); + CreateCriteriaLoaders(); + CombineCriteriaQueries(); - if (log.IsDebugEnabled) - { - log.DebugFormat("Multi criteria with {0} criteria queries.", criteriaQueries.Count); - for (int i = 0; i < criteriaQueries.Count; i++) - { - log.DebugFormat("Query #{0}: {1}", i, criteriaQueries[i]); - } - } + if (log.IsDebugEnabled) + { + log.DebugFormat("Multi criteria with {0} criteria queries.", criteriaQueries.Count); + for (int i = 0; i < criteriaQueries.Count; i++) + { + log.DebugFormat("Query #{0}: {1}", i, criteriaQueries[i]); + } + } - if (cacheable) - { - criteriaResults = ListUsingQueryCache(); - } - else - { - criteriaResults = ListIgnoreQueryCache(); - } + if (cacheable) + { + criteriaResults = ListUsingQueryCache(); + } + else + { + criteriaResults = ListIgnoreQueryCache(); + } - return criteriaResults; + return criteriaResults; + } } Modified: trunk/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs 2009-05-08 01:26:08 UTC (rev 4264) +++ trunk/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs 2009-05-08 01:45:53 UTC (rev 4265) @@ -378,27 +378,30 @@ /// </summary> public IList List() { - bool cacheable = session.Factory.Settings.IsQueryCacheEnabled && isCacheable; - combinedParameters = CreateCombinedQueryParameters(); + using (new SessionIdLoggingContext(session.SessionId)) + { + bool cacheable = session.Factory.Settings.IsQueryCacheEnabled && isCacheable; + combinedParameters = CreateCombinedQueryParameters(); - if (log.IsDebugEnabled) - { - log.DebugFormat("Multi query with {0} queries.", queries.Count); - for (int i = 0; i < queries.Count; i++) - { - log.DebugFormat("Query #{0}: {1}", i, queries[i]); - } - } + if (log.IsDebugEnabled) + { + log.DebugFormat("Multi query with {0} queries.", queries.Count); + for (int i = 0; i < queries.Count; i++) + { + log.DebugFormat("Query #{0}: {1}", i, queries[i]); + } + } - try - { - Before(); - return cacheable ? ListUsingQueryCache() : ListIgnoreQueryCache(); - } - finally - { - After(); - } + try + { + Before(); + return cacheable ? ListUsingQueryCache() : ListIgnoreQueryCache(); + } + finally + { + After(); + } + } } public IMultiQuery SetFlushMode(FlushMode mode) Added: trunk/nhibernate/src/NHibernate/Impl/SessionIdLoggingContext.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/SessionIdLoggingContext.cs (rev 0) +++ trunk/nhibernate/src/NHibernate/Impl/SessionIdLoggingContext.cs 2009-05-08 01:45:53 UTC (rev 4265) @@ -0,0 +1,51 @@ +using System; +using log4net; + +namespace NHibernate.Impl +{ + public class SessionIdLoggingContext : IDisposable + { + private readonly object oldSessonId; + + public SessionIdLoggingContext(Guid id) + { + oldSessonId = SessionId; + SessionId = id; + } + + /// <summary> + /// Error handling in this case will only kick in if we cannot set values on the TLS + /// this is usally the case if we are called from the finalizer, since this is something + /// that we do only for logging, we ignore the error. + /// </summary> + private static object SessionId + { + get + { + try + { + return ThreadContext.Properties["sessionId"]; + } + catch (Exception) + { + return null; + } + } + set + { + try + { + ThreadContext.Properties["sessionId"] = value; + } + catch (Exception) + { + } + } + } + + public void Dispose() + { + SessionId = oldSessonId; + } + } +} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Impl/SessionImpl.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/SessionImpl.cs 2009-05-08 01:26:08 UTC (rev 4264) +++ trunk/nhibernate/src/NHibernate/Impl/SessionImpl.cs 2009-05-08 01:45:53 UTC (rev 4265) @@ -195,32 +195,35 @@ ConnectionReleaseMode connectionReleaseMode) : base(factory) { - if (interceptor == null) - throw new AssertionFailure("The interceptor can not be null."); + using (new SessionIdLoggingContext(sessionId)) + { + if (interceptor == null) + throw new AssertionFailure("The interceptor can not be null."); - rootSession = null; - this.timestamp = timestamp; - this.entityMode = entityMode; - this.interceptor = interceptor; - listeners = factory.EventListeners; - actionQueue = new ActionQueue(this); - persistenceContext = new StatefulPersistenceContext(this); - this.flushBeforeCompletionEnabled = flushBeforeCompletionEnabled; - this.autoCloseSessionEnabled = autoCloseSessionEnabled; - this.connectionReleaseMode = connectionReleaseMode; - connectionManager = new ConnectionManager(this, connection, connectionReleaseMode, interceptor); + rootSession = null; + this.timestamp = timestamp; + this.entityMode = entityMode; + this.interceptor = interceptor; + listeners = factory.EventListeners; + actionQueue = new ActionQueue(this); + persistenceContext = new StatefulPersistenceContext(this); + this.flushBeforeCompletionEnabled = flushBeforeCompletionEnabled; + this.autoCloseSessionEnabled = autoCloseSessionEnabled; + this.connectionReleaseMode = connectionReleaseMode; + connectionManager = new ConnectionManager(this, connection, connectionReleaseMode, interceptor); - if (factory.Statistics.IsStatisticsEnabled) - { - factory.StatisticsImplementor.OpenSession(); - } + if (factory.Statistics.IsStatisticsEnabled) + { + factory.StatisticsImplementor.OpenSession(); + } - if (log.IsDebugEnabled) - { - log.Debug("opened session at timestamp: " + timestamp); - } + if (log.IsDebugEnabled) + { + log.Debug("opened session at timestamp: " + timestamp); + } - CheckAndUpdateSessionStatus(); + CheckAndUpdateSessionStatus(); + } } /// <summary> @@ -231,24 +234,27 @@ private SessionImpl(SessionImpl parent, EntityMode entityMode) :base (parent.Factory) { - rootSession = parent; - timestamp = parent.timestamp; - connectionManager = parent.connectionManager; - interceptor = parent.interceptor; - listeners = parent.listeners; - actionQueue = new ActionQueue(this); - this.entityMode = entityMode; - persistenceContext = new StatefulPersistenceContext(this); - flushBeforeCompletionEnabled = false; - autoCloseSessionEnabled = false; - connectionReleaseMode = parent.ConnectionReleaseMode; // NH different + using (new SessionIdLoggingContext(sessionId)) + { + rootSession = parent; + timestamp = parent.timestamp; + connectionManager = parent.connectionManager; + interceptor = parent.interceptor; + listeners = parent.listeners; + actionQueue = new ActionQueue(this); + this.entityMode = entityMode; + persistenceContext = new StatefulPersistenceContext(this); + flushBeforeCompletionEnabled = false; + autoCloseSessionEnabled = false; + connectionReleaseMode = parent.ConnectionReleaseMode; // NH different - if (Factory.Statistics.IsStatisticsEnabled) - Factory.StatisticsImplementor.OpenSession(); + if (Factory.Statistics.IsStatisticsEnabled) + Factory.StatisticsImplementor.OpenSession(); - log.Debug("opened session [" + entityMode + "]"); + log.Debug("opened session [" + entityMode + "]"); - CheckAndUpdateSessionStatus(); + CheckAndUpdateSessionStatus(); + } } public override FutureCriteriaBatch FutureCriteriaBatch @@ -313,44 +319,47 @@ /// <summary></summary> public IDbConnection Close() { - log.Debug("closing session"); - if (IsClosed) - { - throw new SessionException("Session was already closed"); - } + using (new SessionIdLoggingContext(sessionId)) + { + log.Debug("closing session"); + if (IsClosed) + { + throw new SessionException("Session was already closed"); + } - if (Factory.Statistics.IsStatisticsEnabled) - { - Factory.StatisticsImplementor.CloseSession(); - } + if (Factory.Statistics.IsStatisticsEnabled) + { + Factory.StatisticsImplementor.CloseSession(); + } - try - { - try - { - if (childSessionsByEntityMode != null) - { - foreach (KeyValuePair<EntityMode, ISession> pair in childSessionsByEntityMode) - { - pair.Value.Close(); - } - } - } - catch - { - // just ignore - } + try + { + try + { + if (childSessionsByEntityMode != null) + { + foreach (KeyValuePair<EntityMode, ISession> pair in childSessionsByEntityMode) + { + pair.Value.Close(); + } + } + } + catch + { + // just ignore + } - if (rootSession == null) - return connectionManager.Close(); - else - return null; - } - finally - { - SetClosed(); - Cleanup(); - } + if (rootSession == null) + return connectionManager.Close(); + else + return null; + } + finally + { + SetClosed(); + Cleanup(); + } + } } /// <summary> @@ -360,65 +369,74 @@ /// </summary> public override void AfterTransactionCompletion(bool success, ITransaction tx) { - log.Debug("transaction completion"); - if (Factory.Statistics.IsStatisticsEnabled) - { - Factory.StatisticsImplementor.EndTransaction(success); - } + using (new SessionIdLoggingContext(sessionId)) + { + log.Debug("transaction completion"); + if (Factory.Statistics.IsStatisticsEnabled) + { + Factory.StatisticsImplementor.EndTransaction(success); + } - connectionManager.AfterTransaction(); - persistenceContext.AfterTransactionCompletion(); - actionQueue.AfterTransactionCompletion(success); - if (rootSession == null) - { - try - { - interceptor.AfterTransactionCompletion(tx); - } - catch (Exception t) - { - log.Error("exception in interceptor afterTransactionCompletion()", t); - } - } + connectionManager.AfterTransaction(); + persistenceContext.AfterTransactionCompletion(); + actionQueue.AfterTransactionCompletion(success); + if (rootSession == null) + { + try + { + interceptor.AfterTransactionCompletion(tx); + } + catch (Exception t) + { + log.Error("exception in interceptor afterTransactionCompletion()", t); + } + } - //if (autoClear) - // Clear(); + //if (autoClear) + // Clear(); + } } private void Cleanup() { - persistenceContext.Clear(); + using (new SessionIdLoggingContext(sessionId)) + { + persistenceContext.Clear(); + } } public LockMode GetCurrentLockMode(object obj) { - CheckAndUpdateSessionStatus(); + using (new SessionIdLoggingContext(sessionId)) + { + CheckAndUpdateSessionStatus(); - if (obj == null) - { - throw new ArgumentNullException("obj", "null object passed to GetCurrentLockMode"); - } - if (obj is INHibernateProxy) - { - obj = ((INHibernateProxy)obj).HibernateLazyInitializer.GetImplementation(this); - if (obj == null) - { - return LockMode.None; - } - } + if (obj == null) + { + throw new ArgumentNullException("obj", "null object passed to GetCurrentLockMode"); + } + if (obj is INHibernateProxy) + { + obj = ((INHibernateProxy) obj).HibernateLazyInitializer.GetImplementation(this); + if (obj == null) + { + return LockMode.None; + } + } - EntityEntry e = persistenceContext.GetEntry(obj); - if (e == null) - { - throw new TransientObjectException("Given object not associated with the session"); - } + EntityEntry e = persistenceContext.GetEntry(obj); + if (e == null) + { + throw new TransientObjectException("Given object not associated with the session"); + } - if (e.Status != Status.Loaded) - { - throw new ObjectDeletedException("The given object was deleted", e.Id, e.EntityName); - } - return e.LockMode; + if (e.Status != Status.Loaded) + { + throw new ObjectDeletedException("The given object was deleted", e.Id, e.EntityName); + } + return e.LockMode; + } } public override bool IsOpen @@ -433,12 +451,18 @@ /// <returns></returns> public object Save(object obj) { - return FireSave(new SaveOrUpdateEvent(null, obj, this)); + using (new SessionIdLoggingContext(sessionId)) + { + return FireSave(new SaveOrUpdateEvent(null, obj, this)); + } } public object Save(string entityName, object obj) { - return FireSave(new SaveOrUpdateEvent(entityName, obj, this)); + using (new SessionIdLoggingContext(sessionId)) + { + return FireSave(new SaveOrUpdateEvent(entityName, obj, this)); + } } /// <summary> @@ -448,7 +472,10 @@ /// <param name="id"></param> public void Save(object obj, object id) { - FireSave(new SaveOrUpdateEvent(null, obj, id, this)); + using (new SessionIdLoggingContext(sessionId)) + { + FireSave(new SaveOrUpdateEvent(null, obj, id, this)); + } } /// <summary> @@ -457,38 +484,59 @@ /// <param name="obj"></param> public void Delete(object obj) { - FireDelete(new DeleteEvent(obj, this)); + using (new SessionIdLoggingContext(sessionId)) + { + FireDelete(new DeleteEvent(obj, this)); + } } /// <summary> Delete a persistent object (by explicit entity name)</summary> public void Delete(string entityName, object obj) { - FireDelete(new DeleteEvent(entityName, obj, this)); + using (new SessionIdLoggingContext(sessionId)) + { + FireDelete(new DeleteEvent(entityName, obj, this)); + } } public void Update(object obj) { - FireUpdate(new SaveOrUpdateEvent(null, obj, this)); + using (new SessionIdLoggingContext(sessionId)) + { + FireUpdate(new SaveOrUpdateEvent(null, obj, this)); + } } public void Update(string entityName, object obj) { - FireUpdate(new SaveOrUpdateEvent(entityName, obj, this)); + using (new SessionIdLoggingContext(sessionId)) + { + FireUpdate(new SaveOrUpdateEvent(entityName, obj, this)); + } } public void SaveOrUpdate(object obj) { - FireSaveOrUpdate(new SaveOrUpdateEvent(null, obj, this)); + using (new SessionIdLoggingContext(sessionId)) + { + FireSaveOrUpdate(new SaveOrUpdateEvent(null, obj, this)); + } } public void SaveOrUpdate(string entityName, object obj) { - FireSaveOrUpdate(new SaveOrUpdateEvent(entityName, obj, this)); + using (new SessionIdLoggingContext(sessionId)) + { + FireSaveOrUpdate(new SaveOrUpdateEvent(entityName, obj, this)); + } } public void Update(object obj, object id) { - FireUpdate(new SaveOrUpdateEvent(null, obj, id, this)); + using (new SessionIdLoggingContext(sessionId)) + { + FireUpdate(new SaveOrUpdateEvent(null, obj, id, this)); + } } private static readonly object[] NoArgs = new object[0]; @@ -501,168 +549,219 @@ /// <returns></returns> public IList Find(string query) { - return List(query, new QueryParameters()); + using (new SessionIdLoggingContext(sessionId)) + { + return List(query, new QueryParameters()); + } } public IList Find(string query, object value, IType type) { - return List(query, new QueryParameters(type, value)); + using (new SessionIdLoggingContext(sessionId)) + { + return List(query, new QueryParameters(type, value)); + } } public IList Find(string query, object[] values, IType[] types) { - return List(query, new QueryParameters(types, values)); + using (new SessionIdLoggingContext(sessionId)) + { + return List(query, new QueryParameters(types, values)); + } } public override IList List(string query, QueryParameters parameters) { - IList results = new ArrayList(); - List(query, parameters, results); - return results; + using (new SessionIdLoggingContext(sessionId)) + { + IList results = new ArrayList(); + List(query, parameters, results); + return results; + } } public override IList<T> List<T>(string query, QueryParameters parameters) { - List<T> results = new List<T>(); - List(query, parameters, results); - return results; + using (new SessionIdLoggingContext(sessionId)) + { + List<T> results = new List<T>(); + List(query, parameters, results); + return results; + } } - public override void List(string query, QueryParameters queryParameters, IList results) - { - CheckAndUpdateSessionStatus(); - queryParameters.ValidateParameters(); - HQLQueryPlan plan = GetHQLQueryPlan(query, false); - AutoFlushIfRequired(plan.QuerySpaces); + public override void List(string query, QueryParameters queryParameters, IList results) + { + using (new SessionIdLoggingContext(sessionId)) + { + CheckAndUpdateSessionStatus(); + queryParameters.ValidateParameters(); + HQLQueryPlan plan = GetHQLQueryPlan(query, false); + AutoFlushIfRequired(plan.QuerySpaces); - bool success = false; - dontFlushFromFind++; //stops flush being called multiple times if this method is recursively called - try - { - plan.PerformList(queryParameters, this, results); - success = true; - } - catch (HibernateException) - { - // Do not call Convert on HibernateExceptions - throw; - } - catch (Exception e) - { - throw Convert(e, "Could not execute query"); - } - finally - { - dontFlushFromFind--; - AfterOperation(success); - } - } + bool success = false; + dontFlushFromFind++; //stops flush being called multiple times if this method is recursively called + try + { + plan.PerformList(queryParameters, this, results); + success = true; + } + catch (HibernateException) + { + // Do not call Convert on HibernateExceptions + throw; + } + catch (Exception e) + { + throw Convert(e, "Could not execute query"); + } + finally + { + dontFlushFromFind--; + AfterOperation(success); + } + } + } - public override IQueryTranslator[] GetQueries(string query, bool scalar) + public override IQueryTranslator[] GetQueries(string query, bool scalar) { - HQLQueryPlan plan = Factory.QueryPlanCache.GetHQLQueryPlan(query, scalar, enabledFilters); - AutoFlushIfRequired(plan.QuerySpaces); - return plan.Translators; + using (new SessionIdLoggingContext(sessionId)) + { + HQLQueryPlan plan = Factory.QueryPlanCache.GetHQLQueryPlan(query, scalar, enabledFilters); + AutoFlushIfRequired(plan.QuerySpaces); + return plan.Translators; + } } public IEnumerable Enumerable(string query) { - return Enumerable(query, NoArgs, NoTypes); + using (new SessionIdLoggingContext(sessionId)) + { + return Enumerable(query, NoArgs, NoTypes); + } } public IEnumerable Enumerable(string query, object value, IType type) { - return Enumerable(query, new[] { value }, new[] { type }); + using (new SessionIdLoggingContext(sessionId)) + { + return Enumerable(query, new[] {value}, new[] {type}); + } } public IEnumerable Enumerable(string query, object[] values, IType[] types) { - return Enumerable(query, new QueryParameters(types, values)); + using (new SessionIdLoggingContext(sessionId)) + { + return Enumerable(query, new QueryParameters(types, values)); + } } public override IEnumerable<T> Enumerable<T>(string query, QueryParameters queryParameters) { - CheckAndUpdateSessionStatus(); - queryParameters.ValidateParameters(); - HQLQueryPlan plan = GetHQLQueryPlan(query, true); - AutoFlushIfRequired(plan.QuerySpaces); + using (new SessionIdLoggingContext(sessionId)) + { + CheckAndUpdateSessionStatus(); + queryParameters.ValidateParameters(); + HQLQueryPlan plan = GetHQLQueryPlan(query, true); + AutoFlushIfRequired(plan.QuerySpaces); - dontFlushFromFind++; //stops flush being called multiple times if this method is recursively called - try - { - return plan.PerformIterate<T>(queryParameters, this); - } - finally - { - dontFlushFromFind--; - } + dontFlushFromFind++; //stops flush being called multiple times if this method is recursively called + try + { + return plan.PerformIterate<T>(queryParameters, this); + } + finally + { + dontFlushFromFind--; + } + } } public override IEnumerable Enumerable(string query, QueryParameters queryParameters) { - CheckAndUpdateSessionStatus(); - queryParameters.ValidateParameters(); - HQLQueryPlan plan = GetHQLQueryPlan(query, true); - AutoFlushIfRequired(plan.QuerySpaces); + using (new SessionIdLoggingContext(sessionId)) + { + CheckAndUpdateSessionStatus(); + queryParameters.ValidateParameters(); + HQLQueryPlan plan = GetHQLQueryPlan(query, true); + AutoFlushIfRequired(plan.QuerySpaces); - dontFlushFromFind++; //stops flush being called multiple times if this method is recursively called - try - { - return plan.PerformIterate(queryParameters, this); - } - finally - { - dontFlushFromFind--; - } + dontFlushFromFind++; //stops flush being called multiple times if this method is recursively called + try + { + return plan.PerformIterate(queryParameters, this); + } + finally + { + dontFlushFromFind--; + } + } } // TODO: Scroll(string query, QueryParameters queryParameters) public int Delete(string query) { - return Delete(query, NoArgs, NoTypes); + using (new SessionIdLoggingContext(sessionId)) + { + return Delete(query, NoArgs, NoTypes); + } } public int Delete(string query, object value, IType type) { - return Delete(query, new[] { value }, new[] { type }); + using (new SessionIdLoggingContext(sessionId)) + { + return Delete(query, new[] {value}, new[] {type}); + } } public int Delete(string query, object[] values, IType[] types) { - if (string.IsNullOrEmpty(query)) - { - throw new ArgumentNullException("query", "attempt to perform delete-by-query with null query"); - } + using (new SessionIdLoggingContext(sessionId)) + { + if (string.IsNullOrEmpty(query)) + { + throw new ArgumentNullException("query", "attempt to perform delete-by-query with null query"); + } - CheckAndUpdateSessionStatus(); + CheckAndUpdateSessionStatus(); - if (log.IsDebugEnabled) - { - log.Debug("delete: " + query); - if (values.Length != 0) - { - log.Debug("parameters: " + StringHelper.ToString(values)); - } - } + if (log.IsDebugEnabled) + { + log.Debug("delete: " + query); + if (values.Length != 0) + { + log.Debug("parameters: " + StringHelper.ToString(values)); + } + } - IList list = Find(query, values, types); - int count = list.Count; - for (int i = 0; i < count; i++) - { - Delete(list[i]); - } - return count; + IList list = Find(query, values, types); + int count = list.Count; + for (int i = 0; i < count; i++) + { + Delete(list[i]); + } + return count; + } } public void Lock(object obj, LockMode lockMode) { - FireLock(new LockEvent(obj, lockMode, this)); + using (new SessionIdLoggingContext(sessionId)) + { + FireLock(new LockEvent(obj, lockMode, this)); + } } public void Lock(string entityName, object obj, LockMode lockMode) { - FireLock(new LockEvent(entityName, obj, lockMode, this)); + using (new SessionIdLoggingContext(sessionId)) + { + FireLock(new LockEvent(entityName, obj, lockMode, this)); + } } /// <summary> @@ -673,74 +772,86 @@ /// <returns></returns> public IQuery CreateFilter(object collection, string queryString) { - CheckAndUpdateSessionStatus(); + using (new SessionIdLoggingContext(sessionId)) + { + CheckAndUpdateSessionStatus(); - CheckAndUpdateSessionStatus(); - CollectionFilterImpl filter = - new CollectionFilterImpl(queryString, collection, this, - GetFilterQueryPlan(collection, queryString, null, false).ParameterMetadata); - //filter.SetComment(queryString); - return filter; + CheckAndUpdateSessionStatus(); + CollectionFilterImpl filter = + new CollectionFilterImpl(queryString, collection, this, + GetFilterQueryPlan(collection, queryString, null, false).ParameterMetadata); + //filter.SetComment(queryString); + return filter; + } } private FilterQueryPlan GetFilterQueryPlan(object collection, string filter, QueryParameters parameters, bool shallow) { - if (collection == null) - { - throw new ArgumentNullException("collection", "null collection passed to filter"); - } + using (new SessionIdLoggingContext(sessionId)) + { + if (collection == null) + { + throw new ArgumentNullException("collection", "null collection passed to filter"); + } - CollectionEntry entry = persistenceContext.GetCollectionEntryOrNull(collection); - ICollectionPersister roleBeforeFlush = (entry == null) ? null : entry.LoadedPersister; + CollectionEntry entry = persistenceContext.GetCollectionEntryOrNull(collection); + ICollectionPersister roleBeforeFlush = (entry == null) ? null : entry.LoadedPersister; - FilterQueryPlan plan; - if (roleBeforeFlush == null) - { - // if it was previously unreferenced, we need to flush in order to - // get its state into the database in order to execute query - Flush(); - entry = persistenceContext.GetCollectionEntryOrNull(collection); - ICollectionPersister roleAfterFlush = (entry == null) ? null : entry.LoadedPersister; - if (roleAfterFlush == null) - { - throw new QueryException("The collection was unreferenced"); - } - plan = Factory.QueryPlanCache.GetFilterQueryPlan(filter, roleAfterFlush.Role, shallow, EnabledFilters); - } - else - { - // otherwise, we only need to flush if there are in-memory changes - // to the queried tables - plan = Factory.QueryPlanCache.GetFilterQueryPlan(filter, roleBeforeFlush.Role, shallow, EnabledFilters); - if (AutoFlushIfRequired(plan.QuerySpaces)) - { - // might need to run a different filter entirely after the flush - // because the collection role may have changed - entry = persistenceContext.GetCollectionEntryOrNull(collection); - ICollectionPersister roleAfterFlush = (entry == null) ? null : entry.LoadedPersister; - if (roleBeforeFlush != roleAfterFlush) - { - if (roleAfterFlush == null) - { - throw new QueryException("The collection was dereferenced"); - } - plan = Factory.QueryPlanCache.GetFilterQueryPlan(filter, roleAfterFlush.Role, shallow, EnabledFilters); - } - } - } + FilterQueryPlan plan; + if (roleBeforeFlush == null) + { + // if it was previously unreferenced, we need to flush in order to + // get its state into the database in order to execute query + Flush(); + entry = persistenceContext.GetCollectionEntryOrNull(collection); + ICollectionPersister roleAfterFlush = (entry == null) ? null : entry.LoadedPersister; + if (roleAfterFlush == null) + { + throw new QueryException("The collection was unreferenced"); + } + plan = Factory.QueryPlanCache.GetFilterQueryPlan(filter, roleAfterFlush.Role, shallow, + EnabledFilters); + } + else + { + // otherwise, we only need to flush if there are in-memory changes + // to the queried tables + plan = Factory.QueryPlanCache.GetFilterQueryPlan(filter, roleBeforeFlush.Role, shallow, + EnabledFilters); + if (AutoFlushIfRequired(plan.QuerySpaces)) + { + // might need to run a different filter entirely after the flush + // because the collection role may have changed + entry = persistenceContext.GetCollectionEntryOrNull(collection); + ICollectionPersister roleAfterFlush = (entry == null) ? null : entry.LoadedPersister; + if (roleBeforeFlush != roleAfterFlush) + { + if (roleAfterFlush == null) + { + throw new QueryException("The collection was dereferenced"); + } + plan = Factory.QueryPlanCache.GetFilterQueryPlan(filter, roleAfterFlush.Role, shallow, + EnabledFilters); + } + } + } - if (parameters != null) - { - parameters.PositionalParameterValues[0] = entry.LoadedKey; - parameters.PositionalParameterTypes[0] = entry.LoadedPersister.KeyType; - } + if (parameters != null) + { + parameters.PositionalParameterValues[0] = entry.LoadedKey; + parameters.PositionalParameterTypes[0] = entry.LoadedPersister.KeyType; + } - return plan; + return plan; + } } public override object Instantiate(string clazz, object id) { - return Instantiate(Factory.GetEntityPersister(clazz), id); + using (new SessionIdLoggingContext(sessionId)) + { + return Instantiate(Factory.GetEntityPersister(clazz), id); + } } /// <summary> Get the ActionQueue for this session</summary> @@ -761,101 +872,145 @@ /// <returns></returns> public object Instantiate(IEntityPersister persister, object id) { - ErrorIfClosed(); - object result = interceptor.Instantiate(persister.EntityName, entityMode, id); - if (result == null) - { - result = persister.Instantiate(id, entityMode); - } - return result; + using (new SessionIdLoggingContext(sessionId)) + { + ErrorIfClosed(); + object result = interceptor.Instantiate(persister.EntityName, entityMode, id); + if (result == null) + { + result = persister.Instantiate(id, entityMode); + } + return result; + } } #region IEventSource Members /// <summary> Force an immediate flush</summary> public void ForceFlush(EntityEntry entityEntry) { - CheckAndUpdateSessionStatus(); - if (log.IsDebugEnabled) - { - log.Debug("flushing to force deletion of re-saved object: " + MessageHelper.InfoString(entityEntry.Persister, entityEntry.Id, Factory)); - } + using (new SessionIdLoggingContext(sessionId)) + { + CheckAndUpdateSessionStatus(); + if (log.IsDebugEnabled) + { + log.Debug("flushing to force deletion of re-saved object: " + + MessageHelper.InfoString(entityEntry.Persister, entityEntry.Id, Factory)); + } - if (persistenceContext.CascadeLevel > 0) - { - throw new ObjectDeletedException( - "deleted object would be re-saved by cascade (remove deleted object from associations)", entityEntry.Id, - entityEntry.EntityName); - } + if (persistenceContext.CascadeLevel > 0) + { + throw new ObjectDeletedException( + "deleted object would be re-saved by cascade (remove deleted object from associations)", + entityEntry.Id, + entityEntry.EntityName); + } - Flush(); + Flush(); + } } /// <summary> Cascade merge an entity instance</summary> public void Merge(string entityName, object obj, IDictionary copiedAlready) { - FireMerge(copiedAlready, new MergeEvent(entityName, obj, this)); + using (new SessionIdLoggingContext(sessionId)) + { + FireMerge(copiedAlready, new MergeEvent(entityName, obj, this)); + } } /// <summary> Cascade persist an entity instance</summary> public void Persist(string entityName, object obj, IDictionary createdAlready) { - FirePersist(createdAlready, new PersistEvent(entityName, obj, this)); + using (new SessionIdLoggingContext(sessionId)) + { + FirePersist(createdAlready, new PersistEvent(entityName, obj, this)); + } } /// <summary> Cascade persist an entity instance during the flush process</summary> public void PersistOnFlush(string entityName, object obj, IDictionary copiedAlready) { - FirePersistOnFlush(copiedAlready, new PersistEvent(entityName, obj, this)); + using (new SessionIdLoggingContext(sessionId)) + { + FirePersistOnFlush(copiedAlready, new PersistEvent(entityName, obj, this)); + } } /// <summary> Cascade refresh an entity instance</summary> public void Refresh(object obj, IDictionary refreshedAlready) { - FireRefresh(refreshedAlready, new RefreshEvent(obj, this)); + using (new SessionIdLoggingContext(sessionId)) + { + FireRefresh(refreshedAlready, new RefreshEvent(obj, this)); + } } /// <summary> Cascade copy an entity instance</summary> public void SaveOrUpdateCopy(string entityName, object obj, IDictionary copiedAlready) { - FireSaveOrUpdateCopy(copiedAlready, new MergeEvent(entityName, obj, this)); + using (new SessionIdLoggingContext(sessionId)) + { + FireSaveOrUpdateCopy(copiedAlready, new MergeEvent(entityName, obj, this)); + } } /// <summary> Cascade delete an entity instance</summary> public void Delete(string entityName, object child, bool isCascadeDeleteEnabled, ISet transientEntities) { - FireDelete(new DeleteEvent(entityName, child, isCascadeDeleteEnabled, this), transientEntities); + using (new SessionIdLoggingContext(sessionId)) + { + FireDelete(new DeleteEvent(entityName, child, isCascadeDeleteEnabled, this), transientEntities); + } } #endregion public object Merge(string entityName, object obj) { - return FireMerge(new MergeEvent(entityName, obj, this)); + using (new SessionIdLoggingContext(sessionId)) + { + return FireMerge(new MergeEvent(entityName, obj, this)); + } } public object Merge(object obj) { - return Merge(null, obj); + using (new SessionIdLoggingContext(sessionId)) + { + return Merge(null, obj); + } } public void Persist(string entityName, object obj) { - FirePersist(new PersistEvent(entityName, obj, this)); + using (new SessionIdLoggingContext(sessionId)) + { + FirePersist(new PersistEvent(entityName, obj, this)); + } } public void Persist(object obj) { - Persist(null, obj); + using (new SessionIdLoggingContext(sessionId)) + { + Persist(null, obj); + } } public void PersistOnFlush(string entityName, object obj) { - FirePersistOnFlush(new PersistEvent(entityName, obj, this)); + using (new SessionIdLoggingContext(sessionId)) + { + FirePersistOnFlush(new PersistEvent(entityName, obj, this)); + } } public void PersistOnFlush(object obj) { - Persist(null, obj); + using (new SessionIdLoggingContext(sessionId)) + { + Persist(null, obj); + } } /// <summary></summary> @@ -872,39 +1027,45 @@ public override string BestGuessEntityName(object entity) { - INHibernateProxy proxy = entity as INHibernateProxy; - if (proxy != null) - { - ILazyInitializer initializer = proxy.HibernateLazyInitializer; + using (new SessionIdLoggingContext(sessionId)) + { + INHibernateProxy proxy = entity as INHibernateProxy; + if (proxy != null) + { + ILazyInitializer initializer = proxy.HibernateLazyInitializer; - // it is possible for this method to be called during flush processing, - // so make certain that we do not accidently initialize an uninitialized proxy - if (initializer.IsUninitialized) - { - return initializer.PersistentClass.FullName; - } - entity = initializer.GetImplementation(); - } - EntityEntry entry = persistenceContext.GetEntry(entity); - if (entry == null) - { - return GuessEntityName(entity); - } - else - { - return entry.Persister.EntityName; - } + // it is possible for this method to be called during flush processing, + // so make certain that we do not accidently initialize an uninitialized proxy + if (initializer.IsUninitialized) + { + return initializer.PersistentClass.FullName; + } + entity = initializer.GetImplementation(); + } + EntityEntry entry = persistenceContext.GetEntry(entity); + if (entry == null) + { + return GuessEntityName(entity); + } + else + { + return entry.Persister.EntityName; + } + } } public override string GuessEntityName(object entity) { - string entityName = interceptor.GetEntityName(entity); - if (entityName == null) - { - System.Type t = entity.GetType(); - entityName = Fac... [truncated message content] |