1
1
using System . Linq . Expressions ;
2
+ using NHibernate . Linq . Visitors ;
3
+ using NHibernate . Proxy ;
4
+ using NHibernate . Util ;
2
5
3
6
namespace NHibernate . Linq
4
7
{
@@ -12,7 +15,37 @@ internal static class LinqLogging
12
15
internal static void LogExpression ( string msg , Expression expression )
13
16
{
14
17
if ( Log . IsDebugEnabled )
15
- Log . DebugFormat ( "{0}: {1}" , msg , expression . ToString ( ) ) ;
18
+ {
19
+ // If the expression contains NHibernate proxies, those will be initialized
20
+ // when we call ToString() on the exception. The string representation is
21
+ // generated by a class internal to System.Linq.Expression, so we cannot
22
+ // actually override that logic. Circumvent it by replacing such ConstantExpressions
23
+ // with ParameterExpression, having their name set to the string we wish to display.
24
+ var visitor = new ProxyReplacingExpressionTreeVisitor ( ) ;
25
+ var preparedExpression = visitor . VisitExpression ( expression ) ;
26
+
27
+ Log . DebugFormat ( "{0}: {1}" , msg , preparedExpression . ToString ( ) ) ;
28
+ }
29
+ }
30
+
31
+
32
+ /// <summary>
33
+ /// Replace all occurances of ConstantExpression where the value is an NHibernate
34
+ /// proxy with a ParameterExpression. The name of the parameter will be a string
35
+ /// representing the proxied entity, without initializing it.
36
+ /// </summary>
37
+ private class ProxyReplacingExpressionTreeVisitor : NhExpressionTreeVisitor
38
+ {
39
+ // See also e.g. Remotion.Linq.Clauses.ExpressionTreeVisitors.FormattingExpressionTreeVisitor
40
+ // for another example of this technique.
41
+
42
+ protected override Expression VisitConstantExpression ( ConstantExpression expression )
43
+ {
44
+ if ( expression . Value . IsProxy ( ) )
45
+ return Expression . Parameter ( expression . Type , ObjectUtils . IdentityToString ( expression . Value ) ) ;
46
+
47
+ return base . VisitConstantExpression ( expression ) ;
48
+ }
16
49
}
17
50
}
18
51
}
0 commit comments