Exemple #1
0
        /// <summary>
        ///     This API supports the Entity Framework Core infrastructure and is not intended to be used 
        ///     directly from your code. This API may change or be removed in future releases.
        /// </summary>
        public Migrator(
            [NotNull] IMigrationsAssembly migrationsAssembly,
            [NotNull] IHistoryRepository historyRepository,
            [NotNull] IDatabaseCreator databaseCreator,
            [NotNull] IMigrationsSqlGenerator migrationsSqlGenerator,
            [NotNull] IRawSqlCommandBuilder rawSqlCommandBuilder,
            [NotNull] IMigrationCommandExecutor migrationCommandExecutor,
            [NotNull] IRelationalConnection connection,
            [NotNull] ISqlGenerationHelper sqlGenerationHelper,
            [NotNull] ILogger<Migrator> logger,
            [NotNull] IDatabaseProviderServices providerServices)
        {
            Check.NotNull(migrationsAssembly, nameof(migrationsAssembly));
            Check.NotNull(historyRepository, nameof(historyRepository));
            Check.NotNull(databaseCreator, nameof(databaseCreator));
            Check.NotNull(migrationsSqlGenerator, nameof(migrationsSqlGenerator));
            Check.NotNull(rawSqlCommandBuilder, nameof(rawSqlCommandBuilder));
            Check.NotNull(migrationCommandExecutor, nameof(migrationCommandExecutor));
            Check.NotNull(connection, nameof(connection));
            Check.NotNull(sqlGenerationHelper, nameof(sqlGenerationHelper));
            Check.NotNull(logger, nameof(logger));
            Check.NotNull(providerServices, nameof(providerServices));

            _migrationsAssembly = migrationsAssembly;
            _historyRepository = historyRepository;
            _databaseCreator = (IRelationalDatabaseCreator)databaseCreator;
            _migrationsSqlGenerator = migrationsSqlGenerator;
            _rawSqlCommandBuilder = rawSqlCommandBuilder;
            _migrationCommandExecutor = migrationCommandExecutor;
            _connection = connection;
            _sqlGenerationHelper = sqlGenerationHelper;
            _logger = logger;
            _activeProvider = providerServices.InvariantName;
        }
 public MyQuerySqlGeneratorFactory(
     IRelationalCommandBuilderFactory commandBuilderFactory,
     ISqlGenerationHelper sqlGenerationHelper,
     IParameterNameGeneratorFactory parameterNameGeneratorFactory,
     IRelationalTypeMapper relationalTypeMapper)
     : base(
         commandBuilderFactory,
         sqlGenerationHelper,
         parameterNameGeneratorFactory,
         relationalTypeMapper)
 {
 }
        public RawSqlCommandBuilder(
            [NotNull] IRelationalCommandBuilderFactory relationalCommandBuilderFactory,
            [NotNull] ISqlGenerationHelper sqlGenerationHelper,
            [NotNull] IParameterNameGeneratorFactory parameterNameGeneratorFactory)
        {
            Check.NotNull(relationalCommandBuilderFactory, nameof(relationalCommandBuilderFactory));
            Check.NotNull(sqlGenerationHelper, nameof(sqlGenerationHelper));
            Check.NotNull(parameterNameGeneratorFactory, nameof(parameterNameGeneratorFactory));

            _relationalCommandBuilderFactory = relationalCommandBuilderFactory;
            _sqlGenerationHelper = sqlGenerationHelper;
            _parameterNameGeneratorFactory = parameterNameGeneratorFactory;
        }
        /// <summary>
        ///     This API supports the Entity Framework Core infrastructure and is not intended to be used
        ///     directly from your code. This API may change or be removed in future releases.
        /// </summary>
        public SqliteModificationCommandBatchFactory(
            [NotNull] IRelationalCommandBuilderFactory commandBuilderFactory,
            [NotNull] ISqlGenerationHelper sqlGenerationHelper,
            [NotNull] IUpdateSqlGenerator updateSqlGenerator,
            [NotNull] IRelationalValueBufferFactoryFactory valueBufferFactoryFactory)
        {
            Check.NotNull(commandBuilderFactory, nameof(commandBuilderFactory));
            Check.NotNull(sqlGenerationHelper, nameof(sqlGenerationHelper));
            Check.NotNull(updateSqlGenerator, nameof(updateSqlGenerator));
            Check.NotNull(valueBufferFactoryFactory, nameof(valueBufferFactoryFactory));

            _commandBuilderFactory = commandBuilderFactory;
            _sqlGenerationHelper = sqlGenerationHelper;
            _updateSqlGenerator = updateSqlGenerator;
            _valueBufferFactoryFactory = valueBufferFactoryFactory;
        }
        /// <summary>
        ///     This API supports the Entity Framework Core infrastructure and is not intended to be used
        ///     directly from your code. This API may change or be removed in future releases.
        /// </summary>
        public SqlServerModificationCommandBatchFactory(
            [NotNull] IRelationalCommandBuilderFactory commandBuilderFactory,
            [NotNull] ISqlGenerationHelper sqlGenerationHelper,
            [NotNull] ISqlServerUpdateSqlGenerator updateSqlGenerator,
            [NotNull] IRelationalValueBufferFactoryFactory valueBufferFactoryFactory,
            [NotNull] IDbContextOptions options)
        {
            Check.NotNull(commandBuilderFactory, nameof(commandBuilderFactory));
            Check.NotNull(sqlGenerationHelper, nameof(sqlGenerationHelper));
            Check.NotNull(updateSqlGenerator, nameof(updateSqlGenerator));
            Check.NotNull(valueBufferFactoryFactory, nameof(valueBufferFactoryFactory));
            Check.NotNull(options, nameof(options));

            _commandBuilderFactory = commandBuilderFactory;
            _sqlGenerationHelper = sqlGenerationHelper;
            _updateSqlGenerator = updateSqlGenerator;
            _valueBufferFactoryFactory = valueBufferFactoryFactory;
            _options = options;
        }
 public MyHistoryRepository(
     IDatabaseCreator databaseCreator,
     IRawSqlCommandBuilder rawSqlCommandBuilder,
     IRelationalConnection connection,
     IDbContextOptions options,
     IMigrationsModelDiffer modelDiffer,
     IMigrationsSqlGenerator migrationsSqlGenerator,
     IRelationalAnnotationProvider annotations,
     ISqlGenerationHelper sqlGenerationHelper)
     : base(databaseCreator,
         rawSqlCommandBuilder,
         connection,
         options,
         modelDiffer,
         migrationsSqlGenerator,
         annotations,
         sqlGenerationHelper
         )
 {
 }
 public ConcreteMigrationSqlGenerator(
     IRelationalCommandBuilderFactory commandBuilderFactory,
     ISqlGenerationHelper sqlGenerationHelper,
     IRelationalTypeMapper typeMapper,
     IRelationalAnnotationProvider annotations)
     : base(commandBuilderFactory, sqlGenerationHelper, typeMapper, annotations)
 {
 }
Exemple #8
0
 /// <summary>
 ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
 ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
 ///     any release. You should only use it directly in your code with extreme caution and knowing that
 ///     doing so can result in application failures when updating to a new Entity Framework Core release.
 /// </summary>
 public SqlServerIndexConvention(
     [NotNull] ProviderConventionSetBuilderDependencies dependencies, [NotNull] ISqlGenerationHelper sqlGenerationHelper)
 {
     _sqlGenerationHelper = sqlGenerationHelper;
     Dependencies         = dependencies;
 }
 /// <summary>
 ///     This API supports the Entity Framework Core infrastructure and is not intended to be used
 ///     directly from your code. This API may change or be removed in future releases.
 /// </summary>
 public MySqlIndexConvention([NotNull] ISqlGenerationHelper sqlGenerationHelper)
 {
     _sqlGenerationHelper = sqlGenerationHelper;
 }
Exemple #10
0
 public DefaultFieldParser(ICurrentDbContext CurrentDbContext, ISqlGenerationHelper SqlGenerationHelper, IDbSetFinder DbSetFinder)
 {
     sqlGenerationHelper = SqlGenerationHelper;
     dbSetFinder         = DbSetFinder;
     context             = CurrentDbContext.Context;
 }
Exemple #11
0
 /// <summary>
 ///     Clones this dependency parameter object with one service replaced.
 /// </summary>
 /// <param name="sqlGenerationHelper"> A replacement for the current dependency of this type. </param>
 /// <returns> A new parameter object with the given service replaced. </returns>
 public UpdateSqlGeneratorDependencies With([NotNull] ISqlGenerationHelper sqlGenerationHelper)
 => new UpdateSqlGeneratorDependencies(
     sqlGenerationHelper,
     TypeMappingSource);
Exemple #12
0
 /// <summary>
 ///     Clones this dependency parameter object with one service replaced.
 /// </summary>
 /// <param name="sqlGenerationHelper"> A replacement for the current dependency of this type. </param>
 /// <returns> A new parameter object with the given service replaced. </returns>
 public QuerySqlGeneratorDependencies With([NotNull] ISqlGenerationHelper sqlGenerationHelper)
 => new QuerySqlGeneratorDependencies(
     CommandBuilderFactory,
     sqlGenerationHelper,
     ParameterNameGeneratorFactory,
     TypeMappingSource);
Exemple #13
0
 public ZackQuerySqlGeneratorFactory(QuerySqlGeneratorDependencies dependencies,
                                     ISqlGenerationHelper sqlGenerationHelper)
 {
     this.dependencies         = dependencies;
     this._sqlGenerationHelper = sqlGenerationHelper;
 }
        protected UpdateSqlGenerator([NotNull] ISqlGenerationHelper sqlGenerationHelper)
        {
            Check.NotNull(sqlGenerationHelper, nameof(sqlGenerationHelper));

            SqlGenerationHelper = sqlGenerationHelper;
        }
 /// <summary>
 ///     Clones this dependency parameter object with one service replaced.
 /// </summary>
 /// <param name="sqlGenerationHelper"> A replacement for the current dependency of this type. </param>
 /// <returns> A new parameter object with the given service replaced. </returns>
 public MigrationsSqlGeneratorDependencies With([NotNull] ISqlGenerationHelper sqlGenerationHelper)
 => new MigrationsSqlGeneratorDependencies(
     CommandBuilderFactory,
     UpdateSqlGenerator,
     sqlGenerationHelper,
     TypeMapper);
 public DefaultLolitaUpdateExecutor(ISqlGenerationHelper SqlGenerationHelper)
 {
     _sqlGenerationHelper = SqlGenerationHelper;
 }
Exemple #17
0
 public FbMigrationSqlGeneratorBehavior(ISqlGenerationHelper sqlHelper)
 => _sqlHelper = sqlHelper;
Exemple #18
0
 public WithChangeTracingContextSqlServerModificationCommandBatch(IRelationalCommandBuilderFactory commandBuilderFactory, ISqlGenerationHelper sqlGenerationHelper, ISqlServerUpdateSqlGenerator updateSqlGenerator, IRelationalValueBufferFactoryFactory valueBufferFactoryFactory, int?maxBatchSize)
     : base(commandBuilderFactory, sqlGenerationHelper, updateSqlGenerator, valueBufferFactoryFactory, maxBatchSize)
 {
     _commandBuilderFactory = commandBuilderFactory;
 }
        private static List <string> BuildShardingCmds(MigrationOperation operation, string sourceCmd, ISqlGenerationHelper sqlGenerationHelper)
        {
            //所有MigrationOperation定义
            //https://github.com/dotnet/efcore/tree/b970bf29a46521f40862a01db9e276e6448d3cb0/src/EFCore.Relational/Migrations/Operations
            //ColumnOperation仅替换Table
            //其余其余都是将Name和Table使用分表名替换
            Dictionary <string, List <string> > _existsShardingTables
                = Cache.ServiceProvider.GetService <ShardingContainer>().ExistsShardingTables;

            List <string> resList      = new List <string>();
            string        absTableName = string.Empty;

            string name      = operation.GetPropertyValue("Name") as string;
            string tableName = operation.GetPropertyValue("Table") as string;
            string pattern   = string.Format("^({0})$|^({0}_.*?)$|^(.*?_{0}_.*?)$|^(.*?_{0})$", absTableName);

            Func <KeyValuePair <string, List <string> >, bool> where = x =>
                                                                       _existsShardingTables.Any(x => Regex.IsMatch(name, BuildPattern(x.Key)));

            if (!tableName.IsNullOrEmpty())
            {
                absTableName = tableName;
            }
            else if (!name.IsNullOrEmpty() && _existsShardingTables.Any(x => where (x)))
            {
                absTableName = _existsShardingTables.Where(x => where (x)).FirstOrDefault().Key;
            }

            //分表
            if (!absTableName.IsNullOrEmpty() && _existsShardingTables.ContainsKey(absTableName))
            {
                var shardings = _existsShardingTables[absTableName];
                shardings.ForEach(aShardingTable =>
                {
                    string newCmd = sourceCmd;
                    GetReplaceGroups(operation, absTableName, aShardingTable).ForEach(aReplace =>
                    {
                        newCmd = newCmd.Replace(
                            sqlGenerationHelper.DelimitIdentifier(aReplace.sourceName),
                            sqlGenerationHelper.DelimitIdentifier(aReplace.targetName));
                    });
                    resList.Add(newCmd);
                });
            }

            return(resList);

            string BuildPattern(string absTableName)
            {
                return(string.Format("^({0})$|^({0}_.*?)$|^(.*?_{0}_.*?)$|^(.*?_{0})$", absTableName));
            }
        }
Exemple #20
0
 public ZackQuerySqlGenerator_Npgsql(QuerySqlGeneratorDependencies dependencies, ISqlGenerationHelper sqlGenerationHelper, bool reverseNullOrderingEnabled, Version postgresVersion)
     : base(dependencies, reverseNullOrderingEnabled, postgresVersion)
 {
     this._sqlGenerationHelper = sqlGenerationHelper;
     this.IsForBatchEF         = false;
 }
Exemple #21
0
 public MyCatUpdateSqlGenerator([NotNull] ISqlGenerationHelper SqlGenerationHelper)
     : base(SqlGenerationHelper)
 {
 }
 public SqliteQuerySqlGenerator(
     IRelationalCommandBuilderFactory relationalCommandBuilderFactory,
     ISqlGenerationHelper sqlGenerationHelper)
     : base(relationalCommandBuilderFactory, sqlGenerationHelper)
 {
 }
 public OpenEdgeModificationCommandBatchFactory(IRelationalCommandBuilderFactory commandBuilderFactory, ISqlGenerationHelper sqlGenerationHelper,
                                                IUpdateSqlGenerator updateSqlGenerator, IRelationalValueBufferFactoryFactory valueBufferFactoryFactory, IDbContextOptions options)
 {
     _commandBuilderFactory     = commandBuilderFactory;
     _sqlGenerationHelper       = sqlGenerationHelper;
     _updateSqlGenerator        = updateSqlGenerator;
     _valueBufferFactoryFactory = valueBufferFactoryFactory;
     _options = options;
 }
Exemple #24
0
 public SqliteUpdateSqlGenerator([NotNull] ISqlGenerationHelper sqlGenerationHelper)
     : base(sqlGenerationHelper)
 {
 }
Exemple #25
0
 public MySQLUpdateSqlGenerator(ISqlGenerationHelper sqlGenerator)
     : base(sqlGenerator)
 {
 }
Exemple #26
0
 public FbRelationalTransaction(IRelationalConnection connection, DbTransaction transaction, Guid transactionId, IDiagnosticsLogger <DbLoggerCategory.Database.Transaction> logger, bool transactionOwned, ISqlGenerationHelper sqlGenerationHelper)
     : base(connection, transaction, transactionId, logger, transactionOwned, sqlGenerationHelper)
 {
 }
        public NpgsqlTypeMappingSource([NotNull] TypeMappingSourceDependencies dependencies,
                                       [NotNull] RelationalTypeMappingSourceDependencies relationalDependencies,
                                       [NotNull] ISqlGenerationHelper sqlGenerationHelper,
                                       [CanBeNull] INpgsqlOptions npgsqlOptions = null)
            : base(dependencies, relationalDependencies)
        {
            _sqlGenerationHelper = Check.NotNull(sqlGenerationHelper, nameof(sqlGenerationHelper));

            // Initialize some mappings which depend on other mappings
            _int4range = new NpgsqlRangeTypeMapping("int4range", typeof(NpgsqlRange <int>), _int4, sqlGenerationHelper);
            _int8range = new NpgsqlRangeTypeMapping("int8range", typeof(NpgsqlRange <long>), _int8, sqlGenerationHelper);
            _numrange  = new NpgsqlRangeTypeMapping("numrange", typeof(NpgsqlRange <decimal>), _numeric, sqlGenerationHelper);
            _tsrange   = new NpgsqlRangeTypeMapping("tsrange", typeof(NpgsqlRange <DateTime>), _timestamp, sqlGenerationHelper);
            _tstzrange = new NpgsqlRangeTypeMapping("tstzrange", typeof(NpgsqlRange <DateTime>), _timestamptz, sqlGenerationHelper);
            _daterange = new NpgsqlRangeTypeMapping("daterange", typeof(NpgsqlRange <DateTime>), _timestamptz, sqlGenerationHelper);

            // Note that PostgreSQL has aliases to some built-in type name aliases (e.g. int4 for integer),
            // these are mapped as well.
            // https://www.postgresql.org/docs/current/static/datatype.html#DATATYPE-TABLE
            var storeTypeMappings = new Dictionary <string, RelationalTypeMapping[]>(StringComparer.OrdinalIgnoreCase)
            {
                { "boolean", new[] { _bool } },
                { "bool", new[] { _bool } },
                { "bytea", new[] { _bytea } },
                { "real", new[] { _float4 } },
                { "float4", new[] { _float4 } },
                { "double precision", new[] { _float8 } },
                { "float8", new[] { _float8 } },
                { "numeric", new[] { _numeric } },
                { "decimal", new[] { _numeric } },
                { "money", new[] { _money } },
                { "uuid", new[] { _uuid } },
                { "smallint", new RelationalTypeMapping[] { _int2, _int2Byte } },
                { "int2", new RelationalTypeMapping[] { _int2, _int2Byte } },
                { "integer", new[] { _int4 } },
                { "int", new[] { _int4 } },
                { "int4", new[] { _int4 } },
                { "bigint", new[] { _int8 } },
                { "int8", new[] { _int8 } },
                { "text", new[] { _text } },
                { "jsonb", new[] { _jsonb } },
                { "json", new[] { _json } },
                { "xml", new[] { _xml } },
                { "citext", new[] { _citext } },
                { "character varying", new[] { _varchar } },
                { "varchar", new[] { _varchar } },
                { "character", new[] { _char } },
                { "char", new[] { _char } },
                { "char(1)", new RelationalTypeMapping[] { _singleChar, _stringAsSingleChar } },
                { "character(1)", new RelationalTypeMapping[] { _singleChar, _stringAsSingleChar } },
                { "date", new[] { _date } },
                { "timestamp without time zone", new[] { _timestamp } },
                { "timestamp", new[] { _timestamp } },
                { "timestamp with time zone", new[] { _timestamptz, _timestamptzDto } },
                { "timestamptz", new[] { _timestamptz, _timestamptzDto } },
                { "interval", new[] { _interval } },
                { "time without time zone", new[] { _time } },
                { "time", new[] { _time } },
                { "time with time zone", new[] { _timetz } },
                { "timetz", new[] { _timetz } },
                { "macaddr", new[] { _macaddr } },
                { "macaddr8", new[] { _macaddr8 } },
                { "inet", new[] { _inet } },
                { "cidr", new[] { _cidr } },
                { "bit", new[] { _bit } },
                { "bit varying", new[] { _varbit } },
                { "varbit", new[] { _varbit } },
                { "hstore", new[] { _hstore } },
                { "point", new[] { _point } },
                { "box", new[] { _box } },
                { "line", new[] { _line } },
                { "lseg", new[] { _lseg } },
                { "path", new[] { _path } },
                { "polygon", new[] { _polygon } },
                { "circle", new[] { _circle } },
                { "xid", new[] { _xid } },
                { "oid", new[] { _oid } },
                { "cid", new[] { _cid } },
                { "regtype", new[] { _regtype } },
                { "lo", new[] { _lo } },
                { "tid", new[] { _tid } },

                { "int4range", new[] { _int4range } },
                { "int8range", new[] { _int8range } },
                { "numrange", new[] { _numrange } },
                { "tsrange", new[] { _tsrange } },
                { "tstzrange", new[] { _tstzrange } },
                { "daterange", new[] { _daterange } },

                { "tsquery", new[] { _tsquery } },
                { "tsvector", new[] { _tsvector } },
                { "regconfig", new[] { _regconfig } }
            };

            var clrTypeMappings = new Dictionary <Type, RelationalTypeMapping>
            {
                { typeof(bool), _bool },
Exemple #28
0
 public TaosQuerySqlGenerator(QuerySqlGeneratorDependencies dependencies)
     : base(dependencies)
 {
     _sqlGenerationHelper = dependencies.SqlGenerationHelper;
 }
Exemple #29
0
 public SqlStatementBuilder(ISqlGenerationHelper helper)
 {
     _helper = helper;
 }
Exemple #30
0
 /// <summary>
 ///     Clones this dependency parameter object with one service replaced.
 /// </summary>
 /// <param name="sqlGenerationHelper"> A replacement for the current dependency of this type. </param>
 /// <returns> A new parameter object with the given service replaced. </returns>
 public UpdateSqlGeneratorDependencies With([NotNull] ISqlGenerationHelper sqlGenerationHelper)
 => new UpdateSqlGeneratorDependencies(
     sqlGenerationHelper,
     RelationalTypeMapper);
 public SqlServerUpdateSqlGenerator([NotNull] ISqlGenerationHelper sqlGenerationHelper,
                                    [NotNull] IRelationalTypeMapper typeMapper)
     : base(sqlGenerationHelper)
 {
     _typeMapper = typeMapper;
 }
 public MySqlSetFieldSqlGenerator(ISqlGenerationHelper x) : base(x)
 {
 }
        /// <summary>
        ///     <para>
        ///         Creates the service dependencies parameter object for a <see cref="UpdateSqlGenerator" />.
        ///     </para>
        ///     <para>
        ///         Do not call this constructor directly from either provider or application code as it may change
        ///         as new dependencies are added. Instead, use this type in your constructor so that an instance
        ///         will be created and injected automatically by the dependency injection container. To create
        ///         an instance with some dependent services replaced, first resolve the object from the dependency
        ///         injection container, then replace selected services using the 'With...' methods. Do not call
        ///         the constructor at any point in this process.
        ///     </para>
        ///     <para>
        ///         This API supports the Entity Framework Core infrastructure and is not intended to be used
        ///         directly from your code. This API may change or be removed in future releases.
        ///     </para>
        /// </summary>
        /// <param name="sqlGenerationHelper"> Helpers for generating update SQL. </param>
        public UpdateSqlGeneratorDependencies([NotNull] ISqlGenerationHelper sqlGenerationHelper)
        {
            Check.NotNull(sqlGenerationHelper, nameof(sqlGenerationHelper));

            SqlGenerationHelper = sqlGenerationHelper;
        }
Exemple #34
0
 public DefaultLolitaUpdateExecutor(ICurrentDbContext CurrentDbContext, ISqlGenerationHelper SqlGenerationHelper, IDbSetFinder DbSetFinder)
 {
     sqlGenerationHelper = SqlGenerationHelper;
     dbSetFinder         = DbSetFinder;
     context             = CurrentDbContext.Context;
 }
 public TestModificationCommandBatchFactory(
     IRelationalCommandBuilderFactory commandBuilderfactory,
     ISqlGenerationHelper sqlGenerationHelper,
     IUpdateSqlGenerator updateSqlGenerator,
     IRelationalValueBufferFactoryFactory valueBufferFactoryFactory)
 {
     _commandBuilderFactory = commandBuilderfactory;
     _sqlGenerationHelper = sqlGenerationHelper;
     _updateSqlGenerator = updateSqlGenerator;
     _valueBufferFactoryFactory = valueBufferFactoryFactory;
 }
Exemple #36
0
        private string GenerateSQL(Expression <Func <TEntity, bool> > predicate, bool ignoreQueryFilters, out IReadOnlyDictionary <string, object> parameters)
        {
            if (setters.Count <= 0)
            {
                throw new InvalidOperationException("At least a Set() should be used.");
            }

            ISqlGenerationHelper sqlGenHelpr = this.dbContext.GetService <ISqlGenerationHelper>();

            //every pair of name=value are converted into two columns of Select,
            //for example, Set(b=>b.Age,b=>b.Age+3).Set(b=>b.Name,b=>"tom") is converted into
            //Select(b=>new{b.Age,F1=b.Age+3,b.Name,F2="tom"})
            var parameter = Expression.Parameter(typeof(TEntity), "e");

            Expression[] initializers = new Expression[setters.Count * 2];
            for (var i = 0; i < setters.Count; i++)
            {
                var setter       = setters[i];
                var propertyType = typeof(object);
                initializers[i * 2]     = Expression.Convert(Expression.Invoke(setter.Name, parameter), propertyType);
                initializers[i * 2 + 1] = Expression.Convert(Expression.Invoke(setter.Value, parameter), propertyType);
            }

            // from https://stackoverflow.com/questions/47513122/entity-framework-core-dynamically-build-select-list-with-navigational-propertie
            NewArrayExpression newArrayExp = Expression.NewArrayInit(
                typeof(object), initializers);
            var selectExpression = Expression.Lambda <Func <TEntity, object> >(newArrayExp, parameter);

            IQueryable <TEntity> queryable = this.dbContext.Set <TEntity>();

            if (predicate != null)
            {
                queryable = queryable.Where(predicate);
            }
            IQueryable <object> selectQueryable = queryable.Select(selectExpression);
            var           parsingResult         = selectQueryable.Parse(this.dbContext, ignoreQueryFilters);
            string        tableName             = sqlGenHelpr.DelimitIdentifier(parsingResult.TableName);
            StringBuilder sbSQL = new StringBuilder();

            sbSQL.Append("Update ").Append(tableName).Append(" ")
            .Append("SET ");
            var columns = parsingResult.ProjectionSQL.ToArray();

            if (columns.Length % 2 != 0)
            {
                throw new InvalidOperationException("The count of columns should be even.");
            }
            //combine every two adjacent columns into an assignment expression,
            //for example, select Age,Age+3,Name,"tom" is converted into
            //Age=Age+3,Name="tom"
            var entityType = dbContext.Model.FindEntityType(typeof(TEntity));
            IRelationalTypeMappingSource typeMappingSrc = dbContext.GetService <IRelationalTypeMappingSource>();

            for (int i = 0; i < columns.Length; i = i + 2)
            {
                string columnName     = columns[i];
                string columnValue    = columns[i + 1];
                var    setter         = setters[i / 2];
                var    property       = entityType.GetProperty(setter.PropertyName);
                var    valueConverter = property.GetValueConverter();

                //fix bug start: https://github.com/yangzhongke/Zack.EFCore.Batch/issues/4
                if (valueConverter != null && setter.PropertyType.IsEnum)
                {
                    if (!(setter.Value.Body is ConstantExpression))
                    {
                        throw new NotSupportedException("Only assignment of constant values to enumerated types is supported currently.");
                    }
                    //when expression is put in Select(u=>u.Status), it will not be converted by converter,
                    //so I need convert it manually.
                    int    intValue       = Convert.ToInt32(columnValue);
                    Enum   enumValue      = EnumHelper.FromInt(setter.PropertyType, intValue);
                    object convertedValue = valueConverter.ConvertToProvider(enumValue);
                    var    typeMapping    = typeMappingSrc.FindMapping(property);
                    //single quote string const
                    columnValue = typeMapping.GenerateProviderValueSqlLiteral(convertedValue);
                }
                //fix bug end

                sbSQL.Append(columnName).Append(" = ").Append(columnValue);
                if (i < columns.Length - 2)
                {
                    sbSQL.Append(", ");
                }
            }
            sbSQL.AppendLine();
            if (!string.IsNullOrWhiteSpace(parsingResult.PredicateSQL))
            {
                sbSQL.Append("WHERE ").Append(parsingResult.PredicateSQL);
            }
            parameters = parsingResult.Parameters;
            return(sbSQL.ToString());
        }
 public TemporalSqlGenerator(IRelationalCommandBuilderFactory relationalCommandBuilderFactory, ISqlGenerationHelper sqlGenerationHelper, IParameterNameGeneratorFactory parameterNameGeneratorFactory, IRelationalTypeMapper relationalTypeMapper, SelectExpression selectExpression) : base(relationalCommandBuilderFactory, sqlGenerationHelper, parameterNameGeneratorFactory, relationalTypeMapper, selectExpression)
 {
 }
 public SqlServerIndexConvention([NotNull] ISqlGenerationHelper sqlGenerationHelper)
 {
     _sqlGenerationHelper = sqlGenerationHelper;
 }