/// <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 virtual ValueGenerator Create(IProperty property, SqlServerSequenceValueGeneratorState generatorState, ISqlServerConnection connection)
        {
            Check.NotNull(property, nameof(property));
            Check.NotNull(generatorState, nameof(generatorState));
            Check.NotNull(connection, nameof(connection));

            var type = property.ClrType.UnwrapNullableType().UnwrapEnumType();

            if (type == typeof(long))
            {
                return new SqlServerSequenceHiLoValueGenerator<long>(_rawSqlCommandBuilder, _sqlGenerator, generatorState, connection);
            }

            if (type == typeof(int))
            {
                return new SqlServerSequenceHiLoValueGenerator<int>(_rawSqlCommandBuilder, _sqlGenerator, generatorState, connection);
            }

            if (type == typeof(short))
            {
                return new SqlServerSequenceHiLoValueGenerator<short>(_rawSqlCommandBuilder, _sqlGenerator, generatorState, connection);
            }

            if (type == typeof(byte))
            {
                return new SqlServerSequenceHiLoValueGenerator<byte>(_rawSqlCommandBuilder, _sqlGenerator, generatorState, connection);
            }

            if (type == typeof(char))
            {
                return new SqlServerSequenceHiLoValueGenerator<char>(_rawSqlCommandBuilder, _sqlGenerator, generatorState, connection);
            }

            if (type == typeof(ulong))
            {
                return new SqlServerSequenceHiLoValueGenerator<ulong>(_rawSqlCommandBuilder, _sqlGenerator, generatorState, connection);
            }

            if (type == typeof(uint))
            {
                return new SqlServerSequenceHiLoValueGenerator<uint>(_rawSqlCommandBuilder, _sqlGenerator, generatorState, connection);
            }

            if (type == typeof(ushort))
            {
                return new SqlServerSequenceHiLoValueGenerator<ushort>(_rawSqlCommandBuilder, _sqlGenerator, generatorState, connection);
            }

            if (type == typeof(sbyte))
            {
                return new SqlServerSequenceHiLoValueGenerator<sbyte>(_rawSqlCommandBuilder, _sqlGenerator, generatorState, connection);
            }

            throw new ArgumentException(CoreStrings.InvalidValueGeneratorFactoryProperty(
                nameof(SqlServerSequenceValueGeneratorFactory), property.Name, property.DeclaringEntityType.DisplayName()));
        }
        private async Task <IEnumerable <List <long> > > GenerateValuesInMultipleThreads(int threadCount, int valueCount)
        {
            const int blockSize = 10;

            var serviceProvider = SqlServerTestHelpers.Instance.CreateServiceProvider();

            var sequence = new Model().SqlServer().GetOrAddSequence("Foo");

            sequence.IncrementBy = blockSize;
            var state = new SqlServerSequenceValueGeneratorState(sequence);

            var executor     = new FakeRawSqlCommandBuilder(blockSize);
            var sqlGenerator = new SqlServerUpdateSqlGenerator(
                new UpdateSqlGeneratorDependencies(
                    new SqlServerSqlGenerationHelper(
                        new RelationalSqlGenerationHelperDependencies())),
                new SqlServerTypeMapper(new RelationalTypeMapperDependencies()));

            var tests           = new Func <Task> [threadCount];
            var generatedValues = new List <long> [threadCount];

            for (var i = 0; i < tests.Length; i++)
            {
                var testNumber = i;
                generatedValues[testNumber] = new List <long>();
                tests[testNumber]           = async() =>
                {
                    for (var j = 0; j < valueCount; j++)
                    {
                        var connection = CreateConnection(serviceProvider);
                        var generator  = new SqlServerSequenceHiLoValueGenerator <long>(executor, sqlGenerator, state, connection);

                        var value = j % 2 == 0
                                ? await generator.NextAsync(null)
                                : generator.Next(null);

                        generatedValues[testNumber].Add(value);
                    }
                };
            }

            var tasks = tests.Select(Task.Run).ToArray();

            foreach (var t in tasks)
            {
                await t;
            }

            return(generatedValues);
        }
예제 #3
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 SqlServerSequenceHiLoValueGenerator(
     IRawSqlCommandBuilder rawSqlCommandBuilder,
     ISqlServerUpdateSqlGenerator sqlGenerator,
     SqlServerSequenceValueGeneratorState generatorState,
     ISqlServerConnection connection,
     IRelationalCommandDiagnosticsLogger commandLogger)
     : base(generatorState)
 {
     _sequence             = generatorState.Sequence;
     _rawSqlCommandBuilder = rawSqlCommandBuilder;
     _sqlGenerator         = sqlGenerator;
     _connection           = connection;
     _commandLogger        = commandLogger;
 }
예제 #4
0
        public void Does_not_generate_temp_values()
        {
            var sequence = Sequence.GetOrAddSequence(new Model(), RelationalFullAnnotationNames.Instance.SequencePrefix, "Foo");

            sequence.IncrementBy = 4;
            var state = new SqlServerSequenceValueGeneratorState(sequence);

            var generator = new SqlServerSequenceHiLoValueGenerator <int>(
                new FakeRawSqlCommandBuilder(4),
                new SqlServerUpdateSqlGenerator(new SqlServerSqlGenerationHelper(), new SqlServerTypeMapper()),
                state,
                CreateConnection());

            Assert.False(generator.GeneratesTemporaryValues);
        }
예제 #5
0
        public void Does_not_generate_temp_values()
        {
            var state = new SqlServerSequenceValueGeneratorState(
                new Sequence(
                    new Model(), RelationalAnnotationNames.Prefix, "Foo")
            {
                IncrementBy = 4
            });

            var generator = new SqlServerSequenceHiLoValueGenerator <int>(
                new FakeSqlStatementExecutor(4),
                new SqlServerUpdateSqlGenerator(new SqlServerSqlGenerator()),
                state,
                CreateConnection());

            Assert.False(generator.GeneratesTemporaryValues);
        }
예제 #6
0
        public void Does_not_generate_temp_values()
        {
            var sequence = new Model().SqlServer().GetOrAddSequence("Foo");

            sequence.IncrementBy = 4;
            var state = new SqlServerSequenceValueGeneratorState(sequence);

            var generator = new SqlServerSequenceHiLoValueGenerator <int>(
                new FakeRawSqlCommandBuilder(4),
                new SqlServerUpdateSqlGenerator(
                    new UpdateSqlGeneratorDependencies(
                        new SqlServerSqlGenerationHelper(
                            new RelationalSqlGenerationHelperDependencies()),
                        TestServiceFactory.Instance.Create <SqlServerTypeMapper>())),
                state,
                CreateConnection());

            Assert.False(generator.GeneratesTemporaryValues);
        }
        public void Generates_sequential_values <TValue>()
        {
            const int blockSize = 4;
            const int poolSize  = 3;

            var state     = new SqlServerSequenceValueGeneratorState("Foo", blockSize, poolSize);
            var generator = new SqlServerSequenceValueGenerator <TValue>(new FakeSqlStatementExecutor(blockSize), state, CreateConnection());

            var generatedValues = new List <TValue>();

            for (var i = 0; i < 27; i++)
            {
                generatedValues.Add(generator.Next());
            }

            Assert.Equal(
                new[] { 1, 5, 9, 2, 6, 10, 3, 7, 11, 4, 8, 12, 13, 17, 21, 14, 18, 22, 15, 19, 23, 16, 20, 24, 25, 29, 33 },
                generatedValues.Select(v => (int)Convert.ChangeType(v, typeof(int), CultureInfo.InvariantCulture)));
        }
예제 #8
0
        public void Generates_sequential_values <TValue>()
        {
            const int blockSize = 4;

            var sequence = Sequence.GetOrAddSequence(new Model(), RelationalFullAnnotationNames.Instance.SequencePrefix, "Foo");

            sequence.IncrementBy = blockSize;
            var state = new SqlServerSequenceValueGeneratorState(sequence);

            var generator = new SqlServerSequenceHiLoValueGenerator <TValue>(
                new FakeRawSqlCommandBuilder(blockSize),
                new SqlServerUpdateSqlGenerator(new SqlServerSqlGenerationHelper(), new SqlServerTypeMapper()),
                state,
                CreateConnection());

            for (var i = 1; i <= 27; i++)
            {
                Assert.Equal(i, (int)Convert.ChangeType(generator.Next(null), typeof(int), CultureInfo.InvariantCulture));
            }
        }
        public void Does_not_generate_temp_values()
        {
            var sequence = ((IMutableModel)new Model()).AddSequence("Foo");
            sequence.IncrementBy = 4;
            var state = new SqlServerSequenceValueGeneratorState(sequence);

            var generator = new SqlServerSequenceHiLoValueGenerator<int>(
                new FakeRawSqlCommandBuilder(4),
                new SqlServerUpdateSqlGenerator(
                    new UpdateSqlGeneratorDependencies(
                        new SqlServerSqlGenerationHelper(
                            new RelationalSqlGenerationHelperDependencies()),
                        new SqlServerTypeMappingSource(
                            TestServiceFactory.Instance.Create<TypeMappingSourceDependencies>(),
                            TestServiceFactory.Instance.Create<RelationalTypeMappingSourceDependencies>()))),
                state,
                CreateConnection(),
                new FakeDiagnosticsLogger<DbLoggerCategory.Database.Command>());

            Assert.False(generator.GeneratesTemporaryValues);
        }
        private IList <long>[] GenerateValuesInMultipleThreads(int poolSize, int threadCount, int valueCount)
        {
            const int blockSize = 10;

            var serviceProvider = SqlServerTestHelpers.Instance.CreateServiceProvider();

            var state = new SqlServerSequenceValueGeneratorState(
                new Sequence(
                    new Model(), RelationalAnnotationNames.Prefix, "Foo")
            {
                IncrementBy = blockSize
            },
                poolSize);

            var executor     = new FakeSqlStatementExecutor(blockSize);
            var sqlGenerator = new SqlServerUpdateSqlGenerator();

            var tests           = new Action[threadCount];
            var generatedValues = new List <long> [threadCount];

            for (var i = 0; i < tests.Length; i++)
            {
                var testNumber = i;
                generatedValues[testNumber] = new List <long>();
                tests[testNumber]           = () =>
                {
                    for (var j = 0; j < valueCount; j++)
                    {
                        var connection = CreateConnection(serviceProvider);
                        var generator  = new SqlServerSequenceValueGenerator <long>(executor, sqlGenerator, state, connection);

                        generatedValues[testNumber].Add(generator.Next());
                    }
                };
            }

            Parallel.Invoke(tests);

            return(generatedValues);
        }
예제 #11
0
        public void Generates_sequential_values <TValue>()
        {
            const int blockSize = 4;

            var state = new SqlServerSequenceValueGeneratorState(
                new Sequence(
                    new Model(), RelationalAnnotationNames.Prefix, "Foo")
            {
                IncrementBy = blockSize
            });

            var generator = new SqlServerSequenceHiLoValueGenerator <TValue>(
                new FakeSqlStatementExecutor(blockSize),
                new SqlServerUpdateSqlGenerator(new SqlServerSqlGenerator()),
                state,
                CreateConnection());

            for (var i = 1; i <= 27; i++)
            {
                Assert.Equal(i, (int)Convert.ChangeType(generator.Next(), typeof(int), CultureInfo.InvariantCulture));
            }
        }
예제 #12
0
        private IEnumerable <List <long> > GenerateValuesInMultipleThreads(int threadCount, int valueCount)
        {
            const int blockSize = 10;

            var serviceProvider = SqlServerTestHelpers.Instance.CreateServiceProvider();

            var sequence = Sequence.GetOrAddSequence(new Model(), RelationalFullAnnotationNames.Instance.SequencePrefix, "Foo");

            sequence.IncrementBy = blockSize;
            var state = new SqlServerSequenceValueGeneratorState(sequence);

            var executor     = new FakeRawSqlCommandBuilder(blockSize);
            var sqlGenerator = new SqlServerUpdateSqlGenerator(new SqlServerSqlGenerationHelper(), new SqlServerTypeMapper());

            var tests           = new Action[threadCount];
            var generatedValues = new List <long> [threadCount];

            for (var i = 0; i < tests.Length; i++)
            {
                var testNumber = i;
                generatedValues[testNumber] = new List <long>();
                tests[testNumber]           = () =>
                {
                    for (var j = 0; j < valueCount; j++)
                    {
                        var connection = CreateConnection(serviceProvider);
                        var generator  = new SqlServerSequenceHiLoValueGenerator <long>(executor, sqlGenerator, state, connection);

                        generatedValues[testNumber].Add(generator.Next(null));
                    }
                };
            }

            Parallel.Invoke(tests);

            return(generatedValues);
        }
예제 #13
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 virtual ValueGenerator Create(
        IProperty property,
        SqlServerSequenceValueGeneratorState generatorState,
        ISqlServerConnection connection,
        IRawSqlCommandBuilder rawSqlCommandBuilder,
        IRelationalCommandDiagnosticsLogger commandLogger)
    {
        var type = property.ClrType.UnwrapNullableType().UnwrapEnumType();

        if (type == typeof(long))
        {
            return(new SqlServerSequenceHiLoValueGenerator <long>(
                       rawSqlCommandBuilder, _sqlGenerator, generatorState, connection, commandLogger));
        }

        if (type == typeof(int))
        {
            return(new SqlServerSequenceHiLoValueGenerator <int>(
                       rawSqlCommandBuilder, _sqlGenerator, generatorState, connection, commandLogger));
        }

        if (type == typeof(decimal))
        {
            return(new SqlServerSequenceHiLoValueGenerator <decimal>(
                       rawSqlCommandBuilder, _sqlGenerator, generatorState, connection, commandLogger));
        }

        if (type == typeof(short))
        {
            return(new SqlServerSequenceHiLoValueGenerator <short>(
                       rawSqlCommandBuilder, _sqlGenerator, generatorState, connection, commandLogger));
        }

        if (type == typeof(byte))
        {
            return(new SqlServerSequenceHiLoValueGenerator <byte>(
                       rawSqlCommandBuilder, _sqlGenerator, generatorState, connection, commandLogger));
        }

        if (type == typeof(char))
        {
            return(new SqlServerSequenceHiLoValueGenerator <char>(
                       rawSqlCommandBuilder, _sqlGenerator, generatorState, connection, commandLogger));
        }

        if (type == typeof(ulong))
        {
            return(new SqlServerSequenceHiLoValueGenerator <ulong>(
                       rawSqlCommandBuilder, _sqlGenerator, generatorState, connection, commandLogger));
        }

        if (type == typeof(uint))
        {
            return(new SqlServerSequenceHiLoValueGenerator <uint>(
                       rawSqlCommandBuilder, _sqlGenerator, generatorState, connection, commandLogger));
        }

        if (type == typeof(ushort))
        {
            return(new SqlServerSequenceHiLoValueGenerator <ushort>(
                       rawSqlCommandBuilder, _sqlGenerator, generatorState, connection, commandLogger));
        }

        if (type == typeof(sbyte))
        {
            return(new SqlServerSequenceHiLoValueGenerator <sbyte>(
                       rawSqlCommandBuilder, _sqlGenerator, generatorState, connection, commandLogger));
        }

        throw new ArgumentException(
                  CoreStrings.InvalidValueGeneratorFactoryProperty(
                      nameof(SqlServerSequenceValueGeneratorFactory), property.Name, property.DeclaringEntityType.DisplayName()));
    }