示例#1
0
        private void GenerateFromSql(FromSqlExpression fromSqlExpression)
        {
            var sql = fromSqlExpression.Sql;

            string[] substitutions = null;

            switch (fromSqlExpression.Arguments)
            {
            case ConstantExpression constantExpression
                when constantExpression.Value is CompositeRelationalParameter compositeRelationalParameter:
            {
                var subParameters = compositeRelationalParameter.RelationalParameters;
                substitutions = new string[subParameters.Count];
                for (var i = 0; i < subParameters.Count; i++)
                {
                    substitutions[i] = _sqlGenerationHelper.GenerateParameterNamePlaceholder(subParameters[i].InvariantName);
                }

                _relationalCommandBuilder.AddParameter(compositeRelationalParameter);

                break;
            }
            }

            if (substitutions != null)
            {
                // ReSharper disable once CoVariantArrayConversion
                // InvariantCulture not needed since substitutions are all strings
                sql = string.Format(sql, substitutions);
            }


            _relationalCommandBuilder.AppendLines(sql);
        }
示例#2
0
        private void GenerateFromSql(FromSqlExpression fromSqlExpression)
        {
            var sql = fromSqlExpression.Sql;

            string[] substitutions = null;

            switch (fromSqlExpression.Arguments)
            {
            case ConstantExpression constantExpression
                when constantExpression.Value is CompositeRelationalParameter compositeRelationalParameter:
            {
                var subParameters = compositeRelationalParameter.RelationalParameters;
                substitutions = new string[subParameters.Count];
                for (var i = 0; i < subParameters.Count; i++)
                {
                    substitutions[i] = _sqlGenerationHelper.GenerateParameterNamePlaceholder(subParameters[i].InvariantName);
                }

                _relationalCommandBuilder.AddParameter(compositeRelationalParameter);

                break;
            }

            case ConstantExpression constantExpression
                when constantExpression.Value is object[] constantValues:
            {
                substitutions = new string[constantValues.Length];
                for (var i = 0; i < constantValues.Length; i++)
                {
                    var value = constantValues[i];
                    if (value is RawRelationalParameter rawRelationalParameter)
                    {
                        substitutions[i] = _sqlGenerationHelper.GenerateParameterNamePlaceholder(rawRelationalParameter.InvariantName);
                        _relationalCommandBuilder.AddParameter(rawRelationalParameter);
                    }
                    else if (value is SqlConstantExpression sqlConstantExpression)
                    {
                        substitutions[i] = sqlConstantExpression.TypeMapping.GenerateSqlLiteral(sqlConstantExpression.Value);
                    }
                }

                break;
            }
            }

            if (substitutions != null)
            {
                // ReSharper disable once CoVariantArrayConversion
                // InvariantCulture not needed since substitutions are all strings
#pragma warning disable CA1305 // Specify IFormatProvider
                sql = string.Format(sql, substitutions);
#pragma warning restore CA1305 // Specify IFormatProvider
            }

            _relationalCommandBuilder.AppendLines(sql);
        }
        public static IRelationalCommandBuilder AppendParameter(
            [NotNull] this IRelationalCommandBuilder commandBuilder,
            [NotNull] string name,
            [CanBeNull] object value,
            [NotNull] Type type,
            [NotNull] string invariantName)
        {
            Check.NotNull(commandBuilder, nameof(commandBuilder));
            Check.NotEmpty(name, nameof(name));
            Check.NotNull(type, nameof(type));

            bool?isNullable = null;

            if (type.IsNullableType())
            {
                isNullable = true;
                type       = type.UnwrapNullableType();
            }

            commandBuilder.AddParameter(
                name,
                value,
                t => t.GetMapping(type),
                isNullable,
                invariantName);

            commandBuilder.Instance.Append(name);

            return(commandBuilder);
        }
        protected virtual Expression VisitAsOfTable(TemporalTableExpression tableExpression)
        {
            // This method was modeled on "SqlServerQuerySqlGenerator.VisitTable".
            // Where we deviate, is after printing the table name, we check if temporal constraints
            // need to be applied.

            Sql.Append(_sqlGenerationHelper.DelimitIdentifier(tableExpression.Name, tableExpression.Schema));

            if (tableExpression.AsOfDate != null)
            {
                var name = TEMPORAL_PARAMETER_PREFIX + tableExpression.AsOfDate.Name;
                Sql.Append($" FOR SYSTEM_TIME AS OF @{name}"); //2020-02-28T11:00:00

                if (!_commandbuilder.Parameters.Any(x => x.InvariantName == tableExpression.AsOfDate.Name))
                {
                    _commandbuilder.AddParameter(tableExpression.AsOfDate.Name, name);
                }
            }

            Sql
            .Append(AliasSeparator)
            .Append(_sqlGenerationHelper.DelimitIdentifier(tableExpression.Alias));

            return(tableExpression);
        }
        protected override OeAsyncEnumerator ExecuteScalar(Object dataContext, String sql, IReadOnlyList <KeyValuePair <String, Object> > parameters, Type returnType)
        {
            var dbContext             = (DbContext)dataContext;
            var connection            = dbContext.GetService <IRelationalConnection>();
            var commandBuilderFactory = dbContext.GetService <IRelationalCommandBuilderFactory>();
            IRelationalCommandBuilder commandBuilder = commandBuilderFactory.Create();

            commandBuilder.Append(sql);

            var parameterNameGenerator = dbContext.GetService <IParameterNameGeneratorFactory>().Create();
            var sqlHelper = dbContext.GetService <ISqlGenerationHelper>();

            var parameterValues = new Dictionary <String, Object>(parameters.Count);

            for (int i = 0; i < parameters.Count; i++)
            {
                String invariantName = parameterNameGenerator.GenerateNext();
                String name          = sqlHelper.GenerateParameterName(invariantName);

                commandBuilder.AddParameter(invariantName, name);
                parameterValues.Add(invariantName, parameters[i].Value);
            }

            IRelationalCommand command    = commandBuilder.Build();
            Task <Object>      scalarTask = command.ExecuteScalarAsync(connection, parameterValues);

            return(new OeScalarAsyncEnumeratorAdapter(scalarTask, CancellationToken.None));
        }
 /// <summary>
 ///     Adds a parameter.
 /// </summary>
 /// <param name="commandBuilder">The command builder.</param>
 /// <param name="invariantName">
 ///     The key that identifies this parameter. Note that <see cref="IRelationalParameter" /> just represents a
 ///     placeholder for a parameter and not the actual value. This is because the same command can be
 ///     reused multiple times with different parameter values.
 /// </param>
 /// <param name="name">
 ///     The name to be used for the parameter when the command is executed against the database.
 /// </param>
 /// <returns>The same builder instance so that multiple calls can be chained.</returns>
 public static IRelationalCommandBuilder AddParameter(
     this IRelationalCommandBuilder commandBuilder,
     string invariantName,
     string name)
 => commandBuilder.AddParameter(
     new DynamicRelationalParameter(
         invariantName,
         name,
         commandBuilder.TypeMappingSource));
 public static IRelationalCommandBuilder AddPropertyParameter(
     this IRelationalCommandBuilder commandBuilder,
     string invariantName,
     string name,
     IProperty property)
 => commandBuilder.AddParameter(
     new TypeMappedPropertyRelationalParameter(
         invariantName,
         name,
         property.GetRelationalTypeMapping(),
         property));
        /// <summary>
        ///     Adds a parameter.
        /// </summary>
        /// <param name="commandBuilder"> The command builder. </param>
        /// <param name="invariantName">
        ///     The key that identifies this parameter. Note that <see cref="IRelationalParameter" /> just represents a
        ///     placeholder for a parameter and not the actual value. This is because the same command can be
        ///     reused multiple times with different parameter values.
        /// </param>
        /// <param name="dbParameter"> The DbParameter being added. </param>
        /// <returns> The same builder instance so that multiple calls can be chained. </returns>
        public static IRelationalCommandBuilder AddRawParameter(
            this IRelationalCommandBuilder commandBuilder,
            string invariantName,
            DbParameter dbParameter)
        {
            Check.NotNull(commandBuilder, nameof(commandBuilder));
            Check.NotEmpty(invariantName, nameof(invariantName));
            Check.NotNull(dbParameter, nameof(dbParameter));

            return(commandBuilder.AddParameter(
                       new RawRelationalParameter(invariantName, dbParameter)));
        }
示例#9
0
 /// <summary>
 ///     Adds a parameter.
 /// </summary>
 /// <param name="commandBuilder">The command builder.</param>
 /// <param name="invariantName">
 ///     The key that identifies this parameter. Note that <see cref="IRelationalParameter" /> just represents a
 ///     placeholder for a parameter and not the actual value. This is because the same command can be
 ///     reused multiple times with different parameter values.
 /// </param>
 /// <param name="name">
 ///     The name to be used for the parameter when the command is executed against the database.
 /// </param>
 /// <param name="relationalTypeMapping">The relational type mapping for this parameter.</param>
 /// <param name="nullable">A value indicating whether the parameter could contain a null value.</param>
 /// <returns>The same builder instance so that multiple calls can be chained.</returns>
 public static IRelationalCommandBuilder AddParameter(
     this IRelationalCommandBuilder commandBuilder,
     string invariantName,
     string name,
     RelationalTypeMapping relationalTypeMapping,
     bool?nullable)
 => commandBuilder.AddParameter(
     new TypeMappedRelationalParameter(
         invariantName,
         name,
         relationalTypeMapping,
         nullable));
        public static IRelationalCommandBuilder AddParameter(
            [NotNull] this IRelationalCommandBuilder commandBuilder,
            [NotNull] string name,
            [CanBeNull] object value)
        {
            Check.NotNull(commandBuilder, nameof(commandBuilder));
            Check.NotEmpty(name, nameof(name));

            return(commandBuilder.AddParameter(
                       name,
                       value,
                       t => t.GetMappingForValue(value),
                       value?.GetType().IsNullableType()));
        }
示例#11
0
    /// <summary>
    ///     Adds a parameter that is ultimately represented as multiple <see cref="DbParameter" />s in the
    ///     final command.
    /// </summary>
    /// <param name="commandBuilder">The command builder.</param>
    /// <param name="invariantName">
    ///     The key that identifies this parameter. Note that <see cref="IRelationalParameter" /> just represents a
    ///     placeholder for a parameter and not the actual value. This is because the same command can be
    ///     reused multiple times with different parameter values.
    /// </param>
    /// <param name="subParameters">The parameters to include in the composite.</param>
    /// <returns>The same builder instance so that multiple calls can be chained.</returns>
    public static IRelationalCommandBuilder AddCompositeParameter(
        this IRelationalCommandBuilder commandBuilder,
        string invariantName,
        IReadOnlyList <IRelationalParameter> subParameters)
    {
        if (subParameters.Count > 0)
        {
            commandBuilder.AddParameter(
                new CompositeRelationalParameter(
                    invariantName,
                    subParameters));
        }

        return(commandBuilder);
    }
        /// <summary>
        ///     Adds a parameter.
        /// </summary>
        /// <param name="commandBuilder"> The command builder. </param>
        /// <param name="invariantName">
        ///     The key that identifies this parameter. Note that <see cref="IRelationalParameter" /> just represents a
        ///     placeholder for a parameter and not the actual value. This is because the same command can be
        ///     reused multiple times with different parameter values.
        /// </param>
        /// <param name="name">
        ///     The name to be used for the parameter when the command is executed against the database.
        /// </param>
        /// <returns> The same builder instance so that multiple calls can be chained. </returns>
        public static IRelationalCommandBuilder AddParameter(
            this IRelationalCommandBuilder commandBuilder,
            string invariantName,
            string name)
        {
            Check.NotNull(commandBuilder, nameof(commandBuilder));
            Check.NotEmpty(invariantName, nameof(invariantName));
            Check.NotEmpty(name, nameof(name));

            return(commandBuilder.AddParameter(
                       new DynamicRelationalParameter(
                           Check.NotEmpty(invariantName, nameof(invariantName)),
                           Check.NotEmpty(name, nameof(name)),
                           commandBuilder.TypeMappingSource)));
        }
        private static void AddParameter(
            [NotNull] this IRelationalCommandBuilder commandBuilder,
            [NotNull] string name,
            [CanBeNull] object value,
            [NotNull] Func <IRelationalTypeMapper, RelationalTypeMapping> mapType,
            bool?nullable,
            [CanBeNull] string invariantName)
        {
            Check.NotEmpty(name, nameof(name));
            Check.NotNull(mapType, nameof(mapType));

            commandBuilder.AddParameter(
                commandBuilder.CreateParameter(
                    name, value, mapType, nullable, invariantName));
        }
        public static IRelationalCommandBuilder AddParameter(
            [NotNull] this IRelationalCommandBuilder commandBuilder,
            [NotNull] string name,
            [CanBeNull] object value,
            [NotNull] IProperty property)
        {
            Check.NotNull(commandBuilder, nameof(commandBuilder));
            Check.NotEmpty(name, nameof(name));
            Check.NotNull(property, nameof(property));

            return(commandBuilder.AddParameter(
                       name,
                       value,
                       t => t.GetMapping(property),
                       property.IsNullable));
        }
        /// <summary>
        ///     Adds a parameter.
        /// </summary>
        /// <param name="commandBuilder"> The command builder. </param>
        /// <param name="invariantName">
        ///     The key that identifies this parameter. Note that <see cref="IRelationalParameter" /> just represents a
        ///     placeholder for a parameter and not the actual value. This is because the same command can be
        ///     reused multiple times with different parameter values.
        /// </param>
        /// <param name="name">
        ///     The name to be used for the parameter when the command is executed against the database.
        /// </param>
        /// <param name="property"> The property that the type for this parameter will come from. </param>
        /// <returns> The same builder instance so that multiple calls can be chained. </returns>
        public static IRelationalCommandBuilder AddParameter(
            [NotNull] this IRelationalCommandBuilder commandBuilder,
            [NotNull] string invariantName,
            [NotNull] string name,
            [NotNull] IProperty property)
        {
            Check.NotNull(commandBuilder, nameof(commandBuilder));
            Check.NotEmpty(invariantName, nameof(invariantName));
            Check.NotEmpty(name, nameof(name));
            Check.NotNull(property, nameof(property));

            return(commandBuilder.AddParameter(
                       new TypeMappedRelationalParameter(
                           invariantName,
                           name,
                           property.FindRelationalMapping(),
                           property.IsNullable)));
        }
        public static IRelationalCommandBuilder AddPropertyParameter(
            this IRelationalCommandBuilder commandBuilder,
            string invariantName,
            string name,
            IProperty property)
        {
            Check.NotNull(commandBuilder, nameof(commandBuilder));
            Check.NotEmpty(invariantName, nameof(invariantName));
            Check.NotEmpty(name, nameof(name));
            Check.NotNull(property, nameof(property));

            return(commandBuilder.AddParameter(
                       new TypeMappedPropertyRelationalParameter(
                           invariantName,
                           name,
                           property.GetRelationalTypeMapping(),
                           property)));
        }
        /// <summary>
        ///     Adds a parameter that is ultimately represented as multiple <see cref="DbParameter" />s in the
        ///     final command.
        /// </summary>
        /// <param name="commandBuilder"> The command builder. </param>
        /// <param name="invariantName">
        ///     The key that identifies this parameter. Note that <see cref="IRelationalParameter" /> just represents a
        ///     placeholder for a parameter and not the actual value. This is because the same command can be
        ///     reused multiple times with different parameter values.
        /// </param>
        /// <param name="subParameters"> The parameters to include in the composite. </param>
        /// <returns> The same builder instance so that multiple calls can be chained. </returns>
        public static IRelationalCommandBuilder AddCompositeParameter(
            this IRelationalCommandBuilder commandBuilder,
            string invariantName,
            IReadOnlyList <IRelationalParameter> subParameters)
        {
            Check.NotNull(commandBuilder, nameof(commandBuilder));
            Check.NotEmpty(invariantName, nameof(invariantName));
            Check.NotNull(subParameters, nameof(subParameters));

            if (subParameters.Count > 0)
            {
                commandBuilder.AddParameter(
                    new CompositeRelationalParameter(
                        invariantName,
                        subParameters));
            }

            return(commandBuilder);
        }
        /// <summary>
        ///     Adds a parameter.
        /// </summary>
        /// <param name="commandBuilder"> The command builder. </param>
        /// <param name="invariantName">
        ///     The key that identifies this parameter. Note that <see cref="IRelationalParameter" /> just represents a
        ///     placeholder for a parameter and not the actual value. This is because the same command can be
        ///     reused multiple times with different parameter values.
        /// </param>
        /// <param name="name">
        ///     The name to be used for the parameter when the command is executed against the database.
        /// </param>
        /// <param name="relationalTypeMapping"> The relational type mapping for this parameter. </param>
        /// <param name="nullable"> A value indicating whether the parameter could contain a null value. </param>
        /// <returns> The same builder instance so that multiple calls can be chained. </returns>
        public static IRelationalCommandBuilder AddParameter(
            this IRelationalCommandBuilder commandBuilder,
            string invariantName,
            string name,
            RelationalTypeMapping relationalTypeMapping,
            bool?nullable)
        {
            Check.NotNull(commandBuilder, nameof(commandBuilder));
            Check.NotEmpty(invariantName, nameof(invariantName));
            Check.NotEmpty(name, nameof(name));
            Check.NotNull(relationalTypeMapping, nameof(relationalTypeMapping));

            return(commandBuilder.AddParameter(
                       new TypeMappedRelationalParameter(
                           invariantName,
                           name,
                           relationalTypeMapping,
                           nullable)));
        }
示例#19
0
        protected override Expression VisitSqlParameter(SqlParameterExpression sqlParameterExpression)
        {
            var parameterNameInCommand = _sqlGenerationHelper.GenerateParameterName(sqlParameterExpression.Name);

            if (_relationalCommandBuilder.Parameters
                .All(p => p.InvariantName != sqlParameterExpression.Name))
            {
                _relationalCommandBuilder.AddParameter(
                    sqlParameterExpression.Name,
                    parameterNameInCommand,
                    sqlParameterExpression.TypeMapping,
                    sqlParameterExpression.Type.IsNullableType());
            }

            _relationalCommandBuilder
            .Append(_sqlGenerationHelper.GenerateParameterNamePlaceholder(sqlParameterExpression.Name));

            return(sqlParameterExpression);
        }
示例#20
0
        protected virtual Expression VisitAsOfTable(AsOfTableExpression tableExpression)
        {
            Sql.Append(_sqlGenerationHelper.DelimitIdentifier(tableExpression.Name, tableExpression.Schema));
            if (tableExpression.DateParameter != null)
            {
                var name = "__ef_temporal" + tableExpression.DateParameter.Name;
                Sql.Append($" FOR SYSTEM_TIME AS OF @{name}"); //2020-02-28T11:00:00

                if (!_commandbuilder.Parameters.Any(x => x.InvariantName == tableExpression.DateParameter.Name))
                {
                    _commandbuilder.AddParameter(tableExpression.DateParameter.Name, name);
                }
            }
            Sql
            .Append(AliasSeparator)
            .Append(_sqlGenerationHelper.DelimitIdentifier(tableExpression.Alias));

            return(tableExpression);
        }
        private IRelationalCommand CreateCommand(Object dataContext, String sql, IReadOnlyList <KeyValuePair <String, Object> > parameters, out Dictionary <String, Object> parameterValues)
        {
            var dbContext             = (DbContext)dataContext;
            var commandBuilderFactory = dbContext.GetService <IRelationalCommandBuilderFactory>();
            IRelationalCommandBuilder commandBuilder = commandBuilderFactory.Create();

            commandBuilder.Append(sql);

            var parameterNameGenerator = dbContext.GetService <IParameterNameGeneratorFactory>().Create();
            var sqlHelper = dbContext.GetService <ISqlGenerationHelper>();

            parameterValues = new Dictionary <String, Object>(parameters.Count);
            for (int i = 0; i < parameters.Count; i++)
            {
                String invariantName = parameterNameGenerator.GenerateNext();
                String name          = sqlHelper.GenerateParameterName(invariantName);

                commandBuilder.AddParameter(invariantName, name);
                parameterValues.Add(invariantName, GetParameterCore(parameters[i], name, i));
            }

            return(commandBuilder.Build());
        }
示例#22
0
 /// <summary>
 ///     Adds a parameter.
 /// </summary>
 /// <param name="commandBuilder">The command builder.</param>
 /// <param name="invariantName">
 ///     The key that identifies this parameter. Note that <see cref="IRelationalParameter" /> just represents a
 ///     placeholder for a parameter and not the actual value. This is because the same command can be
 ///     reused multiple times with different parameter values.
 /// </param>
 /// <param name="dbParameter">The DbParameter being added.</param>
 /// <returns>The same builder instance so that multiple calls can be chained.</returns>
 public static IRelationalCommandBuilder AddRawParameter(
     this IRelationalCommandBuilder commandBuilder,
     string invariantName,
     DbParameter dbParameter)
 => commandBuilder.AddParameter(
     new RawRelationalParameter(invariantName, dbParameter));