forked from nhibernate/nhibernate-core
-
Notifications
You must be signed in to change notification settings - Fork 0
/
RemoveCharToIntConversion.cs
75 lines (62 loc) · 2.64 KB
/
RemoveCharToIntConversion.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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
using System;
using System.Linq.Expressions;
using Remotion.Linq.Parsing.ExpressionTreeVisitors.Transformation;
namespace NHibernate.Linq.ExpressionTransformers
{
/// <summary>
/// Remove unwanted char-to-int conversions in binary expressions
/// </summary>
/// <remarks>
/// The LINQ expression tree may contain unwanted type conversions that were not in the original expression written by the user. For example,
/// <c>list.Where(someChar => someChar == 'A')</c> becomes the equivalent of <c>list.Where(someChar => (int)someChar == 55)</c> in the expression
/// tree. Converting this directly to a HQL/SQL statement would yield <code>CAST(x AS INT)</code> which does not work in MSSQLSERVER, and possibly
/// other databases.
/// </remarks>
public class RemoveCharToIntConversion : IExpressionTransformer<BinaryExpression>
{
public Expression Transform(BinaryExpression expression)
{
var lhs = expression.Left;
var rhs = expression.Right;
bool lhsIsConvertExpression = IsConvertExpression(lhs);
bool rhsIsConvertExpression = IsConvertExpression(rhs);
if (!lhsIsConvertExpression && !rhsIsConvertExpression) return expression;
bool lhsIsConstantExpression = IsConstantExpression(lhs);
bool rhsIsConstantExpression = IsConstantExpression(rhs);
if (!lhsIsConstantExpression && !rhsIsConstantExpression) return expression;
var convertExpression = lhsIsConvertExpression ? (UnaryExpression)lhs : (UnaryExpression)rhs;
var constantExpression = lhsIsConstantExpression ? (ConstantExpression)lhs : (ConstantExpression)rhs;
if (convertExpression.Type == typeof(int) && convertExpression.Operand.Type == typeof(char) && constantExpression.Type == typeof(int))
{
var constant = Expression.Constant(Convert.ToChar((int)constantExpression.Value));
if (rhsIsConstantExpression)
return Expression.MakeBinary(expression.NodeType, convertExpression.Operand, constant);
return Expression.MakeBinary(expression.NodeType, constant, convertExpression.Operand);
}
return expression;
}
private static bool IsConvertExpression(Expression expression)
{
return (expression.NodeType == ExpressionType.Convert);
}
private static bool IsConstantExpression(Expression expression)
{
return (expression.NodeType == ExpressionType.Constant);
}
public ExpressionType[] SupportedExpressionTypes
{
get
{
return new[]
{
ExpressionType.Equal,
ExpressionType.NotEqual,
ExpressionType.GreaterThan,
ExpressionType.GreaterThanOrEqual,
ExpressionType.LessThan,
ExpressionType.LessThanOrEqual
};
}
}
}
}