Beispiel #1
0
        static bool EqualsToX(ConstantExpression expr1, ConstantExpression expr2, EqualsToInfo info)
        {
            if (expr1.Value == null && expr2.Value == null)
            {
                return(true);
            }

            if (IsConstantable(expr1.Type))
            {
                return(Equals(expr1.Value, expr2.Value));
            }

            if (expr1.Value == null || expr2.Value == null)
            {
                return(false);
            }

            if (expr1.Value is IQueryable queryable)
            {
                var eq1 = queryable.Expression;
                var eq2 = ((IQueryable)expr2.Value).Expression;

                if (!info.Visited.Contains(eq1))
                {
                    info.Visited.Add(eq1);
                    return(eq1.EqualsTo(eq2, info));
                }
            }
            else if (expr1.Value is IEnumerable list1 && expr2.Value is IEnumerable list2)
            {
                var enum1 = list1.GetEnumerator();
                var enum2 = list2.GetEnumerator();
                using (enum1 as IDisposable)
                    using (enum2 as IDisposable)
                    {
                        while (enum1.MoveNext())
                        {
                            if (!enum2.MoveNext() || !object.Equals(enum1.Current, enum2.Current))
                            {
                                return(false);
                            }
                        }

                        if (enum2.MoveNext())
                        {
                            return(false);
                        }
                    }

                return(true);
            }

            return(!info.CompareConstantValues || expr1.Value == expr2.Value);
        }
Beispiel #2
0
        static bool EqualsToX(NewExpression expr1, NewExpression expr2, EqualsToInfo info)
        {
            if (expr1.Arguments.Count != expr2.Arguments.Count)
            {
                return(false);
            }

            if (expr1.Members == null && expr2.Members != null)
            {
                return(false);
            }

            if (expr1.Members != null && expr2.Members == null)
            {
                return(false);
            }

            if (expr1.Constructor != expr2.Constructor)
            {
                return(false);
            }

            if (expr1.Members != null)
            {
                if (expr1.Members.Count != expr2.Members.Count)
                {
                    return(false);
                }

                for (var i = 0; i < expr1.Members.Count; i++)
                {
                    if (expr1.Members[i] != expr2.Members[i])
                    {
                        return(false);
                    }
                }
            }

            for (var i = 0; i < expr1.Arguments.Count; i++)
            {
                if (!expr1.Arguments[i].EqualsTo(expr2.Arguments[i], info))
                {
                    return(false);
                }
            }

            return(true);
        }
Beispiel #3
0
        static bool EqualsToX(LambdaExpression expr1, LambdaExpression expr2, EqualsToInfo info)
        {
            if (expr1.Parameters.Count != expr2.Parameters.Count || !expr1.Body.EqualsTo(expr2.Body, info))
            {
                return(false);
            }

            for (var i = 0; i < expr1.Parameters.Count; i++)
            {
                if (!expr1.Parameters[i].EqualsTo(expr2.Parameters[i], info))
                {
                    return(false);
                }
            }

            return(true);
        }
Beispiel #4
0
        static bool EqualsToX(NewArrayExpression expr1, NewArrayExpression expr2, EqualsToInfo info)
        {
            if (expr1.Expressions.Count != expr2.Expressions.Count)
            {
                return(false);
            }

            for (var i = 0; i < expr1.Expressions.Count; i++)
            {
                if (!expr1.Expressions[i].EqualsTo(expr2.Expressions[i], info))
                {
                    return(false);
                }
            }

            return(true);
        }
Beispiel #5
0
        static bool EqualsToX(BlockExpression expr1, BlockExpression expr2, EqualsToInfo info)
        {
            for (var i = 0; i < expr1.Expressions.Count; i++)
            {
                if (!expr1.Expressions[i].EqualsTo(expr2.Expressions[i], info))
                {
                    return(false);
                }
            }

            for (var i = 0; i < expr1.Variables.Count; i++)
            {
                if (!expr1.Variables[i].EqualsTo(expr2.Variables[i], info))
                {
                    return(false);
                }
            }

            return(true);
        }
        static bool EqualsToX(MemberExpression expr1, MemberExpression expr2, EqualsToInfo info)
        {
            if (expr1.Member == expr2.Member)
            {
                if (expr1.Expression == expr2.Expression || expr1.Expression.Type == expr2.Expression.Type)
                {
                    if (info.QueryableAccessorDic.Count > 0)
                    {
                        if (info.QueryableAccessorDic.TryGetValue(expr1, out var qa))
                        {
                            return
                                (expr1.Expression.EqualsTo(expr2.Expression, info) &&
                                 qa.Queryable.Expression.EqualsTo(qa.Accessor(expr2).Expression, info));
                        }
                    }
                }

                return(expr1.Expression.EqualsTo(expr2.Expression, info));
            }

            return(false);
        }
Beispiel #7
0
        static bool EqualsTo(
            this Expression expr1,
            Expression expr2,
            EqualsToInfo info)
        {
            if (expr1 == expr2)
            {
                return(true);
            }

            if (expr1 == null || expr2 == null || expr1.NodeType != expr2.NodeType || expr1.Type != expr2.Type)
            {
                return(false);
            }

            switch (expr1.NodeType)
            {
            case ExpressionType.Add:
            case ExpressionType.AddChecked:
            case ExpressionType.And:
            case ExpressionType.AndAlso:
            case ExpressionType.ArrayIndex:
#if FW4 || SILVERLIGHT
            case ExpressionType.Assign:
#endif
            case ExpressionType.Coalesce:
            case ExpressionType.Divide:
            case ExpressionType.Equal:
            case ExpressionType.ExclusiveOr:
            case ExpressionType.GreaterThan:
            case ExpressionType.GreaterThanOrEqual:
            case ExpressionType.LeftShift:
            case ExpressionType.LessThan:
            case ExpressionType.LessThanOrEqual:
            case ExpressionType.Modulo:
            case ExpressionType.Multiply:
            case ExpressionType.MultiplyChecked:
            case ExpressionType.NotEqual:
            case ExpressionType.Or:
            case ExpressionType.OrElse:
            case ExpressionType.Power:
            case ExpressionType.RightShift:
            case ExpressionType.Subtract:
            case ExpressionType.SubtractChecked:
            {
//						var e1 = (BinaryExpression)expr1;
//						var e2 = (BinaryExpression)expr2;
                return
                    (((BinaryExpression)expr1).Method == ((BinaryExpression)expr2).Method &&
                     ((BinaryExpression)expr1).Conversion.EqualsTo(((BinaryExpression)expr2).Conversion, info) &&
                     ((BinaryExpression)expr1).Left.EqualsTo(((BinaryExpression)expr2).Left, info) &&
                     ((BinaryExpression)expr1).Right.EqualsTo(((BinaryExpression)expr2).Right, info));
            }

            case ExpressionType.ArrayLength:
            case ExpressionType.Convert:
            case ExpressionType.ConvertChecked:
            case ExpressionType.Negate:
            case ExpressionType.NegateChecked:
            case ExpressionType.Not:
            case ExpressionType.Quote:
            case ExpressionType.TypeAs:
            case ExpressionType.UnaryPlus:
            {
//						var e1 = (UnaryExpression)expr1;
//						var e2 = (UnaryExpression)expr2;
                return
                    (((UnaryExpression)expr1).Method == ((UnaryExpression)expr2).Method &&
                     ((UnaryExpression)expr1).Operand.EqualsTo(((UnaryExpression)expr2).Operand, info));
            }

            case ExpressionType.Conditional:
            {
//						var e1 = (ConditionalExpression)expr1;
//						var e2 = (ConditionalExpression)expr2;
                return
                    (((ConditionalExpression)expr1).Test.EqualsTo(((ConditionalExpression)expr2).Test, info) &&
                     ((ConditionalExpression)expr1).IfTrue.EqualsTo(((ConditionalExpression)expr2).IfTrue, info) &&
                     ((ConditionalExpression)expr1).IfFalse.EqualsTo(((ConditionalExpression)expr2).IfFalse, info));
            }

            case ExpressionType.Call: return(EqualsToX((MethodCallExpression)expr1, (MethodCallExpression)expr2, info));

            case ExpressionType.Constant: return(EqualsToX((ConstantExpression)expr1, (ConstantExpression)expr2, info));

            case ExpressionType.Invoke: return(EqualsToX((InvocationExpression)expr1, (InvocationExpression)expr2, info));

            case ExpressionType.Lambda: return(EqualsToX((LambdaExpression)expr1, (LambdaExpression)expr2, info));

            case ExpressionType.ListInit: return(EqualsToX((ListInitExpression)expr1, (ListInitExpression)expr2, info));

            case ExpressionType.MemberAccess: return(EqualsToX((MemberExpression)expr1, (MemberExpression)expr2, info));

            case ExpressionType.MemberInit: return(EqualsToX((MemberInitExpression)expr1, (MemberInitExpression)expr2, info));

            case ExpressionType.New: return(EqualsToX((NewExpression)expr1, (NewExpression)expr2, info));

            case ExpressionType.NewArrayBounds:
            case ExpressionType.NewArrayInit: return(EqualsToX((NewArrayExpression)expr1, (NewArrayExpression)expr2, info));

            case ExpressionType.Default: return(true);

            case ExpressionType.Parameter: return(((ParameterExpression)expr1).Name == ((ParameterExpression)expr2).Name);

            case ExpressionType.TypeIs:
            {
//						var e1 = (TypeBinaryExpression)expr1;
//						var e2 = (TypeBinaryExpression)expr2;
                return
                    (((TypeBinaryExpression)expr1).TypeOperand == ((TypeBinaryExpression)expr2).TypeOperand &&
                     ((TypeBinaryExpression)expr1).Expression.EqualsTo(((TypeBinaryExpression)expr2).Expression, info));
            }

#if FW4 || SILVERLIGHT
            case ExpressionType.Block:
                return(EqualsToX((BlockExpression)expr1, (BlockExpression)expr2, info));
#endif
            }

            throw new InvalidOperationException();
        }
Beispiel #8
0
        static bool EqualsToX(MethodCallExpression expr1, MethodCallExpression expr2, EqualsToInfo info)
        {
            if (expr1.Arguments.Count != expr2.Arguments.Count || expr1.Method != expr2.Method)
            {
                return(false);
            }

            if (!expr1.Object.EqualsTo(expr2.Object, info))
            {
                return(false);
            }

            for (var i = 0; i < expr1.Arguments.Count; i++)
            {
                if (!expr1.Arguments[i].EqualsTo(expr2.Arguments[i], info))
                {
                    return(false);
                }
            }

            if (info.QueryableAccessorDic.Count > 0)
            {
                QueryableAccessor qa;

                if (info.QueryableAccessorDic.TryGetValue(expr1, out qa))
                {
                    return(qa.Queryable.Expression.EqualsTo(qa.Accessor(expr2).Expression, info));
                }
            }

            return(true);
        }
Beispiel #9
0
        static bool EqualsToX(InvocationExpression expr1, InvocationExpression expr2, EqualsToInfo info)
        {
            if (expr1.Arguments.Count != expr2.Arguments.Count || !expr1.Expression.EqualsTo(expr2.Expression, info))
            {
                return(false);
            }

            for (var i = 0; i < expr1.Arguments.Count; i++)
            {
                if (!expr1.Arguments[i].EqualsTo(expr2.Arguments[i], info))
                {
                    return(false);
                }
            }

            return(true);
        }
Beispiel #10
0
        static bool EqualsToX(MemberInitExpression expr1, MemberInitExpression expr2, EqualsToInfo info)
        {
            if (expr1.Bindings.Count != expr2.Bindings.Count || !expr1.NewExpression.EqualsTo(expr2.NewExpression, info))
            {
                return(false);
            }

            Func <MemberBinding, MemberBinding, bool> compareBindings = null;

            compareBindings = (b1, b2) =>
            {
                if (b1 == b2)
                {
                    return(true);
                }

                if (b1 == null || b2 == null || b1.BindingType != b2.BindingType || b1.Member != b2.Member)
                {
                    return(false);
                }

                switch (b1.BindingType)
                {
                case MemberBindingType.Assignment:
                    return(((MemberAssignment)b1).Expression.EqualsTo(((MemberAssignment)b2).Expression, info));

                case MemberBindingType.ListBinding:
                    var ml1 = (MemberListBinding)b1;
                    var ml2 = (MemberListBinding)b2;

                    if (ml1.Initializers.Count != ml2.Initializers.Count)
                    {
                        return(false);
                    }

                    for (var i = 0; i < ml1.Initializers.Count; i++)
                    {
                        var ei1 = ml1.Initializers[i];
                        var ei2 = ml2.Initializers[i];

                        if (ei1.AddMethod != ei2.AddMethod || ei1.Arguments.Count != ei2.Arguments.Count)
                        {
                            return(false);
                        }

                        for (var j = 0; j < ei1.Arguments.Count; j++)
                        {
                            if (!ei1.Arguments[j].EqualsTo(ei2.Arguments[j], info))
                            {
                                return(false);
                            }
                        }
                    }

                    break;

                case MemberBindingType.MemberBinding:
                    var mm1 = (MemberMemberBinding)b1;
                    var mm2 = (MemberMemberBinding)b2;

                    if (mm1.Bindings.Count != mm2.Bindings.Count)
                    {
                        return(false);
                    }

                    for (var i = 0; i < mm1.Bindings.Count; i++)
                    {
                        if (!compareBindings(mm1.Bindings[i], mm2.Bindings[i]))
                        {
                            return(false);
                        }
                    }

                    break;
                }

                return(true);
            };

            for (var i = 0; i < expr1.Bindings.Count; i++)
            {
                var b1 = expr1.Bindings[i];
                var b2 = expr2.Bindings[i];

                if (!compareBindings(b1, b2))
                {
                    return(false);
                }
            }

            return(true);
        }
        static bool EqualsToX(MethodCallExpression expr1, MethodCallExpression expr2, EqualsToInfo info)
        {
            if (expr1.Arguments.Count != expr2.Arguments.Count || expr1.Method != expr2.Method)
            {
                return(false);
            }

            if (!expr1.Object.EqualsTo(expr2.Object, info))
            {
                return(false);
            }

            var parameters = expr1.Method.GetParameters();

            var dependentParameters = _queryDependentMethods.GetOrAdd(
                expr1.Method, mi =>
            {
                var arr = parameters
                          .Select(p => p.GetCustomAttributes(typeof(SqlQueryDependentAttribute), false).OfType <SqlQueryDependentAttribute>().FirstOrDefault())
                          .ToArray();

                return(arr.Any(a => a != null) ? arr : null);
            });

            if (dependentParameters == null)
            {
                for (var i = 0; i < expr1.Arguments.Count; i++)
                {
                    if (!expr1.Arguments[i].EqualsTo(expr2.Arguments[i], info))
                    {
                        return(false);
                    }
                }
            }
            else
            {
                for (var i = 0; i < expr1.Arguments.Count; i++)
                {
                    var dependentAttribute = dependentParameters[i];

                    if (dependentAttribute != null)
                    {
                        var obj1 = expr1.Arguments[i].EvaluateExpression();
                        var obj2 = expr2.Arguments[i].EvaluateExpression();

                        if (!dependentAttribute.ObjectsEqual(obj1, obj2))
                        {
                            return(false);
                        }
                    }
                    else
                    if (!expr1.Arguments[i].EqualsTo(expr2.Arguments[i], info))
                    {
                        return(false);
                    }
                }
            }

            if (info.QueryableAccessorDic.Count > 0)
            {
                if (info.QueryableAccessorDic.TryGetValue(expr1, out var qa))
                {
                    return(qa.Queryable.Expression.EqualsTo(qa.Accessor(expr2).Expression, info));
                }
            }

            return(true);
        }
Beispiel #12
0
        static bool EqualsToX(MethodCallExpression expr1, MethodCallExpression expr2, EqualsToInfo info)
        {
            if (expr1.Arguments.Count != expr2.Arguments.Count || expr1.Method != expr2.Method)
            {
                return(false);
            }

            if (!expr1.Object.EqualsTo(expr2.Object, info))
            {
                return(false);
            }

            var parameters = expr1.Method.GetParameters();

            var dependentParameters = _queryDependentMethods.GetOrAdd(
                expr1.Method, mi =>
            {
                var arr = parameters
                          .Select(p => p.GetCustomAttributes(typeof(SqlQueryDependentAttribute), false).OfType <SqlQueryDependentAttribute>().FirstOrDefault())
                          .ToArray();

                return(arr.Any(a => a != null) ? arr : null);
            });

            bool DefaultCompareArguments(Expression arg1, Expression arg2)
            {
                if (typeof(Sql.IQueryableContainer).IsSameOrParentOf(arg1.Type))
                {
                    if (arg1.NodeType == ExpressionType.Constant && arg2.NodeType == ExpressionType.Constant)
                    {
                        var query1 = ((Sql.IQueryableContainer)arg1.EvaluateExpression()).Query;
                        var query2 = ((Sql.IQueryableContainer)arg2.EvaluateExpression()).Query;
                        return(EqualsTo(query1.Expression, query2.Expression, info));
                    }
                }
                if (!arg1.EqualsTo(arg2, info))
                {
                    return(false);
                }
                return(true);
            }

            if (dependentParameters == null)
            {
                for (var i = 0; i < expr1.Arguments.Count; i++)
                {
                    if (!DefaultCompareArguments(expr1.Arguments[i], expr2.Arguments[i]))
                    {
                        return(false);
                    }
                }
            }
            else
            {
                for (var i = 0; i < expr1.Arguments.Count; i++)
                {
                    var dependentAttribute = dependentParameters[i];

                    if (dependentAttribute != null)
                    {
                        if (!dependentAttribute.ExpressionsEqual(expr1.Arguments[i], expr2.Arguments[i], (e1, e2) => e1.EqualsTo(e2, info)))
                        {
                            return(false);
                        }
                    }
                    else
                    {
                        if (!DefaultCompareArguments(expr1.Arguments[i], expr2.Arguments[i]))
                        {
                            return(false);
                        }
                    }
                }
            }

            if (info.QueryableAccessorDic.Count > 0)
            {
                if (info.QueryableAccessorDic.TryGetValue(expr1, out var qa))
                {
                    return(qa.Queryable.Expression.EqualsTo(qa.Accessor(expr2).Expression, info));
                }
            }

            return(true);
        }
        static bool EqualsToX(MethodCallExpression expr1, MethodCallExpression expr2, EqualsToInfo info)
        {
            if (expr1.Arguments.Count != expr2.Arguments.Count || expr1.Method != expr2.Method)
            {
                return(false);
            }

            if (!expr1.Object.EqualsTo(expr2.Object, info))
            {
                return(false);
            }

            var parameters = expr1.Method.GetParameters();

            for (var i = 0; i < expr1.Arguments.Count; i++)
            {
                if (parameters[i].GetCustomAttributes(typeof(SqlQueryDependentAttribute), false).Any())
                {
                    if (!Equals(expr1.Arguments[i].EvaluateExpression(), expr2.Arguments[i].EvaluateExpression()))
                    {
                        return(false);
                    }
                }
                else
                if (!expr1.Arguments[i].EqualsTo(expr2.Arguments[i], info))
                {
                    return(false);
                }
            }

            if (info.QueryableAccessorDic.Count > 0)
            {
                QueryableAccessor qa;

                if (info.QueryableAccessorDic.TryGetValue(expr1, out qa))
                {
                    return(qa.Queryable.Expression.EqualsTo(qa.Accessor(expr2).Expression, info));
                }
            }

            return(true);
        }