Пример #1
0
        public override SqlFragment Visit(DbLikeExpression expression)
        {
            LikeFragment f = new LikeFragment();

            f.Argument = expression.Argument.Accept(this);
            f.Pattern  = expression.Pattern.Accept(this);

            return(f);
        }
Пример #2
0
        protected virtual SqlFragment VisitBinaryExpression(DbExpression left, DbExpression right, string op)
        {
            // Optimization: try to use 'like' instead of 'locate' (Edm.IndexOf) for these
            // cases: (like 'word%'), (like '%word') & (like '%word%').
            LikeFragment like = TryPromoteToLike(left, right, op);

            if (like != null)
            {
                return(like);
            }
            // normal flow
            BinaryFragment f = new BinaryFragment();

            f.Operator  = op;
            f.Left      = left.Accept(this);
            f.WrapLeft  = ShouldWrapExpression(left);
            f.Right     = right.Accept(this);
            f.WrapRight = ShouldWrapExpression(right);
            // Optimization, try to promote to In expression
            // NOTE: In EF6, this optimization is already done, we just implement Visit(DbInExpression).
            return(f);
        }
Пример #3
0
        /// <summary>
        /// Examines a binary expression to see if it is an special case suitable to conversion
        /// to a more efficient and equivalent LIKE sql expression.
        /// </summary>
        /// <param name="left"></param>
        /// <param name="right"></param>
        /// <param name="op"></param>
        /// <returns></returns>
        protected LikeFragment TryPromoteToLike(DbExpression left, DbExpression right, string op)
        {
            DbFunctionExpression fl = left as DbFunctionExpression;

            if ((fl != null) && (right is DbConstantExpression))
            {
                LikeFragment like = new LikeFragment();
                if (fl.Function.FullName == "Edm.IndexOf")
                {
                    DbParameterReferenceExpression par;
                    DbPropertyExpression           prop;
                    int value = Convert.ToInt32(((DbConstantExpression)right).Value);
                    like.Argument = fl.Arguments[1].Accept(this);
                    if ((value == 1) && (op == "="))
                    {
                        DbFunctionExpression fr1;
                        DbFunctionExpression fr2;
                        if ((fl.Arguments[0] is DbConstantExpression))
                        {
                            // Case LIKE 'pattern%'
                            DbConstantExpression c = (DbConstantExpression)fl.Arguments[0];
                            like.Pattern = new LiteralFragment(string.Format("'{0}%'", c.Value.ToString().Replace("'", "''")));
                            return(like);
                        }
                        else if ((fl.Arguments.Count == 2) &&
                                 ((fr1 = fl.Arguments[0] as DbFunctionExpression) != null) &&
                                 ((fr2 = fl.Arguments[1] as DbFunctionExpression) != null) &&
                                 (fr1.Function.FullName == "Edm.Reverse") &&
                                 (fr2.Function.FullName == "Edm.Reverse"))
                        {
                            // Case LIKE '%pattern' in EF .NET 4.0
                            if (fr1.Arguments[0] is DbConstantExpression)
                            {
                                DbConstantExpression c = (DbConstantExpression)fr1.Arguments[0];
                                like.Pattern  = new LiteralFragment(string.Format("'%{0}'", c.Value.ToString().Replace("'", "''")));
                                like.Argument = fr2.Arguments[0].Accept(this);
                                return(like);
                            }
                            else if ( /* For EF6 */
                                ((par = fr1.Arguments[0] as DbParameterReferenceExpression) != null) &&
                                ((prop = fr2.Arguments[0] as DbPropertyExpression) != null))
                            {
                                // Pattern LIKE "%..." in EF6
                                like.Pattern  = par.Accept(this);
                                like.Argument = prop.Accept(this);
                                return(like);
                            }
                        }
                        else if ((fl.Arguments.Count == 2) &&
                                 ((par = fl.Arguments[0] as DbParameterReferenceExpression) != null) &&
                                 ((prop = fl.Arguments[1] as DbPropertyExpression) != null))
                        {
                            // Case LIKE "pattern%" in EF6
                            like.Pattern  = par.Accept(this);
                            like.Argument = prop.Accept(this);
                            return(like);
                        }
                    }
                    else if (value == 0)
                    {
                        if (op == ">")
                        {
                            if (fl.Arguments[0] is DbConstantExpression)
                            {
                                // Case LIKE '%pattern%'
                                DbConstantExpression c = (DbConstantExpression)fl.Arguments[0];
                                like.Pattern = new LiteralFragment(string.Format("%{0}%", c.Value.ToString()));
                                return(like);
                            }
                            else if ((par = fl.Arguments[0] as DbParameterReferenceExpression) != null)
                            {
                                // Case LIKE "%pattern%" in EF6
                                like.Pattern = fl.Arguments[0].Accept(this);
                                return(like);
                            }
                        }
                    }
                }
                // Like '%pattern' in EF .NET 3.5 (yes, is different than in .NET 4.0)
                else if (fl.Function.FullName == "Edm.Right")
                {
                    DbFunctionExpression fLength = fl.Arguments[1] as DbFunctionExpression;
                    if ((fLength != null) && (fLength.Function.FullName == "Edm.Length") && (fLength.Arguments[0] is DbConstantExpression))
                    {
                        DbConstantExpression c2 = fLength.Arguments[0] as DbConstantExpression;
                        DbConstantExpression c1 = (DbConstantExpression)right;
                        if (c1.Value == c2.Value)
                        {
                            like.Argument = fl.Arguments[0].Accept(this);
                            like.Pattern  = new LiteralFragment(string.Format("'%{0}'", c1.Value.ToString().Replace("'", "''")));
                            return(like);
                        }
                    }
                }
            }
            return(null);
        }
Пример #4
0
 public void Visit(LikeFragment f)
 {
 }