-
Notifications
You must be signed in to change notification settings - Fork 934
/
Copy pathLinqLogging.cs
50 lines (44 loc) · 1.81 KB
/
LinqLogging.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
using System.Linq.Expressions;
using NHibernate.Linq.Visitors;
using NHibernate.Proxy;
using NHibernate.Util;
namespace NHibernate.Linq
{
internal static class LinqLogging
{
private static readonly INHibernateLogger Log = NHibernateLogger.For("NHibernate.Linq");
/// <summary>
/// If debug logging is enabled, log a string such as "msg: expression.ToString()".
/// </summary>
internal static void LogExpression(string msg, Expression expression)
{
if (Log.IsDebugEnabled())
{
// If the expression contains NHibernate proxies, those will be initialized
// when we call ToString() on the exception. The string representation is
// generated by a class internal to System.Linq.Expression, so we cannot
// actually override that logic. Circumvent it by replacing such ConstantExpressions
// with ParameterExpression, having their name set to the string we wish to display.
var visitor = new ProxyReplacingExpressionVisitor();
var preparedExpression = visitor.Visit(expression);
Log.Debug("{0}: {1}", msg, preparedExpression.ToString());
}
}
/// <summary>
/// Replace all occurrences of ConstantExpression where the value is an NHibernate
/// proxy with a ParameterExpression. The name of the parameter will be a string
/// representing the proxied entity, without initializing it.
/// </summary>
private class ProxyReplacingExpressionVisitor : NhExpressionVisitor
{
// See also e.g. Remotion.Linq.Clauses.ExpressionVisitors.FormattingExpressionTreeVisitor
// for another example of this technique.
protected override Expression VisitConstant(ConstantExpression expression)
{
if (expression.Value.IsProxy())
return Expression.Parameter(expression.Type, ObjectHelpers.IdentityToString(expression.Value));
return base.VisitConstant(expression);
}
}
}
}