Ejemplo n.º 1
0
            private void UnaryExpression(UnaryExpression body, SqlBuilderState state)
            {
                // simple case of a ! prior to a function call
                if (body.NodeType == ExpressionType.Not && body.Operand is MethodCallExpression)
                {
                    MethodCallExpression(body.Operand as MethodCallExpression, state, true);
                    return;
                }

                // simple case of a ! prior to a property call
                if (body.NodeType == ExpressionType.Not && body.Operand is MemberExpression)
                {
                    MemberExpression(body.Operand as MemberExpression, state, true);
                    return;
                }

                // simple case of a ! prior to a binary expression
                if (body.NodeType == ExpressionType.Not && body.Operand is BinaryExpression)
                {
                    BinaryExpression(body.Operand as BinaryExpression, state, true);
                    return;
                }

                throw new NotSupportedException();
            }
Ejemplo n.º 2
0
            public void Interpret(MethodCallExpression expression, SqlBuilderState state)
            {
                var orderByExpression = expression.Arguments[1];

                if (orderByExpression is UnaryExpression)
                {
                    var unaryOrderByExpression = orderByExpression as UnaryExpression;
                    var operandExpression      = unaryOrderByExpression.Operand as Expression;
                    if (operandExpression is LambdaExpression)
                    {
                        var lamdaOperandExpression = operandExpression as LambdaExpression;
                        var bodyExpression         = lamdaOperandExpression.Body;
                        if (bodyExpression is MemberExpression)
                        {
                            var memberBodyExpression = bodyExpression as MemberExpression;
                            var mi        = memberBodyExpression.Member;
                            var fieldName = GetFieldName(mi);
                            state.OrderBy.Add(string.Format("t.[{0}]{1}", fieldName, Ascending ? string.Empty : " DESC"));
                        }
                        else
                        {
                            throw new NotImplementedException("Unable to resolve value for OrderBy");
                        }
                    }
                    else
                    {
                        throw new NotImplementedException("Unable to resolve value for OrderBy");
                    }
                }
                else
                {
                    throw new NotImplementedException("Unable to resolve value for OrderBy");
                }
            }
            public void Interpret(MethodCallExpression expression, SqlBuilderState state)
            {
                var primaryKeyExpression = expression.Arguments[1];

                if (primaryKeyExpression is ConstantExpression)
                {
                    // create a new expression to do the where clause
                    var elementType = expression.Type;
                    var tableInfo   = GetTableInfo(elementType);

                    // check that there is a primary key
                    if (tableInfo.PrimaryKeyFieldNames.Count == 0)
                    {
                        throw new NotSupportedException(string.Format("Type {0} does not have any members with the [Key] attribute applied", elementType.Name));
                    }

                    // can only deal with single element primary keys at the moment
                    if (tableInfo.PrimaryKeyFieldNames.Count > 1)
                    {
                        throw new NotImplementedException(string.Format("Type {0} has more than one member with the [Key] attribute applied", elementType.Name));
                    }

                    // add the parameter and where clause
                    string parameterName = state.GetNextParameter();
                    state.Parameters.Add(parameterName, (primaryKeyExpression as ConstantExpression).Value);
                    state.Where.AppendFormat("( [{0}] = @{1} )", tableInfo.PrimaryKeyFieldNames[0], parameterName);
                }
                else
                {
                    throw new NotSupportedException("Unable to resolve value for RowAt()");
                }
            }
 public void Interpret( MethodCallExpression expression, SqlBuilderState state )
 {
   var orderByExpression = expression.Arguments[ 1 ];
   if ( orderByExpression is UnaryExpression )
   {
     var unaryOrderByExpression = orderByExpression as UnaryExpression;
     var operandExpression = unaryOrderByExpression.Operand as Expression;
     if ( operandExpression is LambdaExpression )
     {
       var lamdaOperandExpression = operandExpression as LambdaExpression;
       var bodyExpression = lamdaOperandExpression.Body;
       if ( bodyExpression is MemberExpression )
       {
         var memberBodyExpression = bodyExpression as MemberExpression;
         var mi = memberBodyExpression.Member;
         var fieldName = GetFieldName( mi );
         state.OrderBy.Add( string.Format( "t.[{0}]{1}", fieldName, Ascending ? string.Empty : " DESC" ) );
       }
       else
         throw new NotImplementedException( "Unable to resolve value for OrderBy" );
     }
     else
       throw new NotImplementedException( "Unable to resolve value for OrderBy" );
   }
   else
     throw new NotImplementedException( "Unable to resolve value for OrderBy" );
 }
Ejemplo n.º 5
0
 private void ProcessExpression(Expression expression, SqlBuilderState state)
 {
     if (expression is LambdaExpression)
     {
         var lambdaOperandExpression = expression as LambdaExpression;
         ProcessExpression(lambdaOperandExpression.Body, state);
     }
     else if (expression is UnaryExpression)
     {
         UnaryExpression(expression as UnaryExpression, state);
     }
     else if (expression is BinaryExpression)
     {
         BinaryExpression(expression as BinaryExpression, state);
     }
     else if (expression is MemberExpression)
     {
         MemberExpression(expression as MemberExpression, state);
     }
     else if (expression is MethodCallExpression)
     {
         MethodCallExpression(expression as MethodCallExpression, state);
     }
     else
     {
         throw new NotSupportedException();
     }
 }
      public void Interpret( MethodCallExpression expression, SqlBuilderState state )
      {
        var primaryKeyExpression = expression.Arguments[ 1 ];
        if ( primaryKeyExpression is ConstantExpression )
        {
          // create a new expression to do the where clause
          var elementType = expression.Type;
          var tableInfo = GetTableInfo( elementType );
          
          // check that there is a primary key
          if ( tableInfo.PrimaryKeyFieldNames.Count == 0 )
            throw new NotSupportedException( string.Format( "Type {0} does not have any members with the [Key] attribute applied", elementType.Name ) );

          // can only deal with single element primary keys at the moment
          if ( tableInfo.PrimaryKeyFieldNames.Count > 1 )
            throw new NotImplementedException( string.Format( "Type {0} has more than one member with the [Key] attribute applied", elementType.Name ) );

          // add the parameter and where clause
          string parameterName = state.GetNextParameter();
          state.Parameters.Add( parameterName, ( primaryKeyExpression as ConstantExpression ).Value );
          state.Where.AppendFormat( "( [{0}] = @{1} )", tableInfo.PrimaryKeyFieldNames[0], parameterName );
        }
        else
          throw new NotSupportedException( "Unable to resolve value for RowAt()" );
      }
        private static string BuildSqlStatement(SqlBuilderState state)
        {
            // get the database table name from the type or the table attribute
            TableInfo table = GetTableInfo(state.ElementType);

            // if there were no specific fields then add the field names from the type
            if (state.FieldNames.Count == 0)
            {
                state.FieldNames.AddRange(table.FieldNames);
            }

            // build up the SQL
            var sb = new StringBuilder("SELECT ");

            // append the top + fields
            if (state.Top.HasValue)
            {
                state.Parameters.Add("top", state.Top.Value, DbType.Int32);
                sb.Append("TOP (@top) ");
            }

            // distinct
            if (state.Distinct)
            {
                sb.Append("DISTINCT ");
            }

            // field list
            sb.Append(string.Join(", ", state.FieldNames.Select(m => "t.[" + m + "]")));

            // append the from
            sb.AppendFormat(" FROM [{0}].[{1}] AS t ", table.SchemaName, table.TableName);

            // append the hints
            if (state.Hints.Count > 0)
            {
                sb.Append("WITH (");
                sb.Append(string.Join(", ", state.Hints));
                sb.Append(")");
            }

            // append the where clause
            if (state.Where.Length != 0)
            {
                sb.Append("WHERE ");
                sb.Append(state.Where.ToString());
            }

            // append the order by
            if (state.OrderBy.Count > 0)
            {
                state.OrderBy.Reverse();
                sb.Append("ORDER BY ");
                sb.Append(string.Join(", ", state.OrderBy));
            }

            return(sb.ToString());
        }
 public override void Interpret( MethodCallExpression expression, SqlBuilderState state )
 {
   state.Top = 1; // to ensure that just the first row is returned
   var whereExpression = expression.Arguments[ 1 ];
   if ( whereExpression is UnaryExpression )
   {
     base.Interpret( expression, state );
   }
   else
     throw new NotSupportedException( "Unable to resolve value for First()" );
 }
 public override void Interpret( MethodCallExpression expression, SqlBuilderState state )
 {
   state.Top = 2; // to ensure that more than one row is return if the expression isn't actually returning a single
   var whereExpression = expression.Arguments[ 1 ];
   if ( whereExpression is UnaryExpression )
   {
     base.Interpret( expression, state );
   }
   else
     throw new NotSupportedException( "Unable to resolve value for Single()" );
 }
Ejemplo n.º 10
0
 private void MemberExpression(MemberExpression body, SqlBuilderState state, bool reversed = false)
 {
     if (body.Member.Name == Nullable_HasValue.Name)
     {
         string fieldName = GetFieldName((body.Expression as MemberExpression).Member);
         state.Where.AppendFormat(" ( t.[{0}] IS {1}NULL ) ", fieldName, reversed ? string.Empty : "NOT ");
     }
     else
     {
         throw new NotSupportedException();
     }
 }
    private static string BuildSqlStatement( SqlBuilderState state )
    {
      // get the database table name from the type or the table attribute
      TableInfo table = GetTableInfo( state.ElementType );

      // if there were no specific fields then add the field names from the type
      if ( state.FieldNames.Count == 0 ) state.FieldNames.AddRange( table.FieldNames );

      // build up the SQL
      var sb = new StringBuilder( "SELECT " );

      // append the top + fields
      if ( state.Top.HasValue )
      {
        state.Parameters.Add( "top", state.Top.Value, DbType.Int32 );
        sb.Append( "TOP (@top) " );
      }

      // distinct
      if ( state.Distinct ) sb.Append( "DISTINCT " );

      // field list
      sb.Append( string.Join( ", ", state.FieldNames.Select( m => "t.[" + m + "]" ) ) );

      // append the from
      sb.AppendFormat( " FROM [{0}].[{1}] AS t ", table.SchemaName, table.TableName );

      // append the hints
      if ( state.Hints.Count > 0 )
      {
        sb.Append( "WITH (" );
        sb.Append( string.Join( ", ", state.Hints ) );
        sb.Append( ")" );
      }

      // append the where clause
      if ( state.Where.Length != 0 )
      {
        sb.Append( "WHERE " );
        sb.Append( state.Where.ToString() );
      }

      // append the order by
      if ( state.OrderBy.Count > 0 )
      {
        state.OrderBy.Reverse();
        sb.Append( "ORDER BY " );
        sb.Append( string.Join( ", ", state.OrderBy ) );
      }

      return sb.ToString();
    }
 public void Interpret( MethodCallExpression expression, SqlBuilderState state )
 {
   var topExpression = expression.Arguments[ 1 ];
   if ( topExpression is ConstantExpression )
   {
     var constantTopExpression = topExpression as ConstantExpression;
     if ( constantTopExpression.Type == typeof( Int32 ) )
       state.Top = (int)constantTopExpression.Value;
     else
       state.Top = Convert.ToInt32( constantTopExpression.Value );
   }
   else
     throw new NotSupportedException( "Unable to resolve value for Take()" );
 }
        private void EvaluateExpression()
        {
            if (_evaluated)
            {
                return;
            }

            var state = new SqlBuilderState();

            var expression = _expression;

            while (expression != null)
            {
                if (expression is ConstantExpression)
                {
                    var constantExpression = expression as ConstantExpression;
                    expression = null; // end of the line

                    // should be an IQueryable<T> where T is the resulting table
                    state.ElementType = constantExpression.Type.GetGenericArguments()[0];
                }
                else if (expression is MethodCallExpression)
                {
                    var methodCallExpression = expression as MethodCallExpression;
                    if (methodCallExpression.Arguments.Count == 0)
                    {
                        throw new NotSupportedException("Method call expression must have at least one argument");
                    }

                    // up the stack of expressions
                    expression = methodCallExpression.Arguments[0];

                    // process each method
                    LinqProcessor.Process(methodCallExpression.Method.Name).Interpret(methodCallExpression, state);
                }
                else
                {
                    throw new NotImplementedException("Expression is not handled");
                }
            }

            // NICE: put the field list into a concurrent shared dictionary

            _sql = BuildSqlStatement(state);
            if (state.HasParameters)
            {
                _parameters = state.Parameters;
            }
            _evaluated = true;
        }
Ejemplo n.º 14
0
            public override void Interpret(MethodCallExpression expression, SqlBuilderState state)
            {
                state.Top = 1; // to ensure that just the first row is returned
                var whereExpression = expression.Arguments[1];

                if (whereExpression is UnaryExpression)
                {
                    base.Interpret(expression, state);
                }
                else
                {
                    throw new NotSupportedException("Unable to resolve value for First()");
                }
            }
Ejemplo n.º 15
0
            public override void Interpret(MethodCallExpression expression, SqlBuilderState state)
            {
                state.Top = 2; // to ensure that more than one row is return if the expression isn't actually returning a single
                var whereExpression = expression.Arguments[1];

                if (whereExpression is UnaryExpression)
                {
                    base.Interpret(expression, state);
                }
                else
                {
                    throw new NotSupportedException("Unable to resolve value for Single()");
                }
            }
Ejemplo n.º 16
0
            public virtual void Interpret(MethodCallExpression expression, SqlBuilderState state)
            {
                var whereExpression = expression.Arguments[1];

                if (whereExpression is UnaryExpression)
                {
                    var unaryWhereExpression = whereExpression as UnaryExpression;
                    var operandExpression    = unaryWhereExpression.Operand;
                    ProcessExpression(operandExpression, state);
                }
                else
                {
                    throw new NotSupportedException("Unable to resolve value for Where()");
                }
            }
            public void Interpret(MethodCallExpression expression, SqlBuilderState state)
            {
                var topExpression = expression.Arguments[1];

                if (topExpression is ConstantExpression)
                {
                    var constantTopExpression = topExpression as ConstantExpression;
                    if (constantTopExpression.Type == typeof(Int32))
                    {
                        state.Top = (int)constantTopExpression.Value;
                    }
                    else
                    {
                        state.Top = Convert.ToInt32(constantTopExpression.Value);
                    }
                }
                else
                {
                    throw new NotSupportedException("Unable to resolve value for Take()");
                }
            }
    private void EvaluateExpression()
    {
      if ( _evaluated ) return;

      var state = new SqlBuilderState();

      var expression = _expression;
      while ( expression != null )
      {
        if ( expression is ConstantExpression )
        {
          var constantExpression = expression as ConstantExpression;
          expression = null; // end of the line

          // should be an IQueryable<T> where T is the resulting table
          state.ElementType = constantExpression.Type.GetGenericArguments()[ 0 ];
        }
        else if ( expression is MethodCallExpression )
        {
          var methodCallExpression = expression as MethodCallExpression;
          if ( methodCallExpression.Arguments.Count == 0 )
            throw new NotSupportedException( "Method call expression must have at least one argument" );

          // up the stack of expressions
          expression = methodCallExpression.Arguments[ 0 ];

          // process each method
          LinqProcessor.Process( methodCallExpression.Method.Name ).Interpret( methodCallExpression, state );
        }
        else
          throw new NotImplementedException( "Expression is not handled" );
      }

      // NICE: put the field list into a concurrent shared dictionary

      _sql = BuildSqlStatement( state );
      if ( state.HasParameters ) _parameters = state.Parameters;
      _evaluated = true;
    }
Ejemplo n.º 19
0
 public void Interpret(MethodCallExpression expression, SqlBuilderState state)
 {
     state.Hints.Add("holdlock");
 }
 public void Interpret(MethodCallExpression expression, SqlBuilderState state)
 {
     state.Distinct = true;
 }
 public void Interpret( MethodCallExpression expression, SqlBuilderState state )
 {
   state.Hints.Add( "holdlock" );
 }
Ejemplo n.º 22
0
 public void Interpret(MethodCallExpression expression, SqlBuilderState state)
 {
     throw new NotImplementedException(string.Format("DapperLinq does not support the {0}() method", (expression as MethodCallExpression).Method.Name));
 }
Ejemplo n.º 23
0
            private void BinaryExpression(BinaryExpression body, SqlBuilderState state, bool inverse = false)
            {
                var left  = body.Left;
                var right = body.Right;

                if (body.NodeType == ExpressionType.AndAlso || body.NodeType == ExpressionType.OrElse)
                {
                    if (inverse)
                    {
                        state.Where.Append("( NOT ");
                    }
                    state.Where.Append("( ");
                    ProcessExpression(left, state);
                    state.Where.Append(body.NodeType == ExpressionType.AndAlso ? " AND " : " OR ");
                    ProcessExpression(right, state);
                    state.Where.Append(" )");
                    if (inverse)
                    {
                        state.Where.Append(" )");
                    }
                }
                else
                {
                    // reverse where applicable
                    bool reversed = false;
                    if (left is ConstantExpression && right is MemberExpression)
                    {
                        reversed = true;
                        var swap = right;
                        right = left;
                        left  = swap;
                    }

                    if (right is ConstantExpression && left is MemberExpression)
                    {
                        string fieldName = GetFieldName((left as MemberExpression).Member);
                        object value     = (right as ConstantExpression).Value;
                        // caching this would lead to caching one or the other depending on whether the original value was NULL or not!
                        // could optimise out non-nullable values
                        if (value == null)
                        {
                            if (body.NodeType == ExpressionType.Equal || body.NodeType == ExpressionType.NotEqual)
                            {
                                bool equal = body.NodeType == ExpressionType.Equal;
                                if (inverse)
                                {
                                    equal = !equal;
                                }
                                state.Where.AppendFormat(" ( t.[{0}] {1} NULL ) ", fieldName, equal ? "IS" : "IS NOT");
                                return;
                            }
                            else
                            {
                                throw new NotSupportedException();
                            }
                        }
                        else
                        {
                            Operator op;
                            if (!_comparisonOperators.TryGetValue(body.NodeType, out op))
                            {
                                throw new NotSupportedException();
                            }

                            string parameterName = state.GetNextParameter();
                            if (!reversed)
                            {
                                state.Where.AppendFormat(" ( t.[{0}] {1} @{2} ) ", fieldName, op.Value(inverse), parameterName);
                            }
                            else
                            {
                                state.Where.AppendFormat(" ( @{2} {1} t.[{0}] ) ", fieldName, op.Value(inverse), parameterName);
                            }

                            state.Parameters.Add(parameterName, value);
                        }
                    }
                    else if (left is MemberExpression && right is MemberExpression)
                    {
                        Operator op;
                        if (!_comparisonOperators.TryGetValue(body.NodeType, out op))
                        {
                            throw new NotSupportedException();
                        }

                        if (!reversed)
                        {
                            state.Where.AppendFormat(" ( t.[{0}] {1} t.[{2}] ) ", GetFieldName((left as MemberExpression).Member), op.Value(inverse), GetFieldName((right as MemberExpression).Member));
                        }
                        else
                        {
                            state.Where.AppendFormat(" ( t.[{2}] {1} t.[{0}] ) ", GetFieldName((left as MemberExpression).Member), op.Value(inverse), GetFieldName((right as MemberExpression).Member));
                        }
                    }
                    else
                    {
                        throw new NotSupportedException();
                    }
                }
            }
 public void Interpret( MethodCallExpression expression, SqlBuilderState state )
 {
   state.Distinct = true;
 }
Ejemplo n.º 25
0
            private void MethodCallExpression(MethodCallExpression body, SqlBuilderState state, bool inverse = false)
            {
                string negative = inverse ? "NOT " : string.Empty;

                if (body.Method == String_IsNullOrEmpty)
                {
                    string fieldName = GetFieldName((body.Arguments[0] as MemberExpression).Member);
                    state.Where.AppendFormat(" ( t.[{0}] IS {1}NULL ) ", fieldName, negative);
                }
                else if (body.Method == String_EndsWith || body.Method == String_EndsWithAndComparison)
                {
                    string     fieldName       = GetFieldName((body.Object as MemberExpression).Member);
                    Expression valueExpression = body.Arguments[0];

                    // if comparison is provide ensure it's one that SQL server will respect
                    if (body.Arguments.Count == 2)
                    {
                        CheckArgumentIsValue <StringComparison>(body.Arguments[1], StringComparison.OrdinalIgnoreCase, "EndsWith can only be used with StringComparison.OrdinalIgnoreCase");
                    }

                    if (valueExpression is ConstantExpression)
                    {
                        var constantValueExpression = valueExpression as ConstantExpression;
                        var parameter = state.GetNextParameter();
                        if (constantValueExpression.Type == typeof(string) && constantValueExpression.Value != null)
                        {
                            string value = (string)constantValueExpression.Value;
                            state.Parameters.Add(parameter, "%" + value);
                            state.Where.AppendFormat(" ( t.[{0}] {1}LIKE @{2} )", fieldName, negative, parameter);
                        }
                        else
                        {
                            throw new NotSupportedException();
                        }
                    }
                    else
                    {
                        throw new NotSupportedException();
                    }
                }
                else if (body.Method == String_StartsWith || body.Method == String_StartsWithAndComparison)
                {
                    string     fieldName       = GetFieldName((body.Object as MemberExpression).Member);
                    Expression valueExpression = body.Arguments[0];

                    // if comparison is provide ensure it's one that SQL server will respect
                    if (body.Arguments.Count == 2)
                    {
                        CheckArgumentIsValue <StringComparison>(body.Arguments[1], StringComparison.OrdinalIgnoreCase, "StartsWith can only be used with StringComparison.OrdinalIgnoreCase");
                    }

                    if (valueExpression is ConstantExpression)
                    {
                        var constantValueExpression = valueExpression as ConstantExpression;
                        var parameter = state.GetNextParameter();
                        if (constantValueExpression.Type == typeof(string) && constantValueExpression.Value != null)
                        {
                            string value = (string)constantValueExpression.Value;
                            state.Parameters.Add(parameter, value + "%");
                            state.Where.AppendFormat(" ( t.[{0}] {1}LIKE @{2} )", fieldName, negative, parameter);
                        }
                        else
                        {
                            throw new NotSupportedException();
                        }
                    }
                    else
                    {
                        throw new NotSupportedException();
                    }
                }
                else if (body.Method == String_Contains)
                {
                    string     fieldName       = GetFieldName((body.Object as MemberExpression).Member);
                    Expression valueExpression = body.Arguments[0];
                    if (valueExpression is ConstantExpression)
                    {
                        var constantValueExpression = valueExpression as ConstantExpression;
                        var parameter = state.GetNextParameter();
                        if (constantValueExpression.Type == typeof(string) && constantValueExpression.Value != null)
                        {
                            string value = (string)constantValueExpression.Value;
                            state.Parameters.Add(parameter, "%" + value + "%");
                            state.Where.AppendFormat(" ( t.[{0}] {1}LIKE @{2} )", fieldName, negative, parameter);
                        }
                        else
                        {
                            throw new NotSupportedException();
                        }
                    }
                    else
                    {
                        throw new NotSupportedException();
                    }
                }
                else
                {
                    throw new NotSupportedException();
                }
            }
 public void Interpret( MethodCallExpression expression, SqlBuilderState state )
 {
   throw new NotImplementedException( string.Format( "DapperLinq does not support the {0}() method", ( expression as MethodCallExpression ).Method.Name ) );
 }