Index: src/NHibernate.Linq/src/NHibernate.Linq/Visitors/Evaluator.cs
===================================================================
--- src/NHibernate.Linq/src/NHibernate.Linq/Visitors/Evaluator.cs (revision 1432)
+++ src/NHibernate.Linq/src/NHibernate.Linq/Visitors/Evaluator.cs (working copy)
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
+using System.Reflection;
namespace NHibernate.Linq.Visitors
{
@@ -76,12 +77,143 @@
if (e.NodeType == ExpressionType.Lambda)
return e;
+ Expression condensed = new Condensor().Visit(e);
+ if (condensed.NodeType == ExpressionType.Constant)
+ return condensed;
+
LambdaExpression lambda = Expression.Lambda(e);
Delegate fn = lambda.Compile();
return Expression.Constant(fn.DynamicInvoke(null), e.Type);
}
}
+ ///
+ /// Brings certain basic expression patterns closer to the surface to
+ /// avoid a lambda compile and dynamic invoke in simple cases
+ ///
+ class Condensor : ExpressionVisitor
+ {
+ protected override Expression VisitMemberAccess(MemberExpression m)
+ {
+ Expression exp = Visit(m.Expression);
+
+ object constant;
+ if (m.NodeType== ExpressionType.MemberAccess && TryGetConstant(exp, out constant))
+ {
+ if (m.Member.MemberType == MemberTypes.Field)
+ {
+ FieldInfo field = (FieldInfo) m.Member;
+ object value = field.GetValue(constant);
+ return Expression.Constant(value, m.Type);
+ }
+ }
+
+ if (exp != m.Expression)
+ {
+ return Expression.MakeMemberAccess(exp, m.Member);
+ }
+ return m;
+ }
+
+
+ protected override Expression VisitUnary(UnaryExpression u) {
+ Expression operand = Visit(u.Operand);
+
+ object constant;
+ if (u.NodeType== ExpressionType.Convert && TryGetConstant(operand, out constant))
+ {
+ if (u.Method == null)
+ {
+ Func