public override bool AddCommand(ModificationCommand modificationCommand)
        {
            Check.NotNull(modificationCommand, nameof(modificationCommand));

            if (ModificationCommands.Count == 0)
            {
                ResetCommandText();
            }

            if (!CanAddCommand(modificationCommand))
            {
                return false;
            }

            _modificationCommands.Add(modificationCommand);
            _resultSetEnd.Add(true);

            if (!IsCommandTextValid())
            {
                ResetCommandText();
                _modificationCommands.RemoveAt(_modificationCommands.Count - 1);
                _resultSetEnd.RemoveAt(_resultSetEnd.Count - 1);
                return false;
            }

            return true;
        }
        public override void AppendUpdateOperation(
            StringBuilder commandStringBuilder,
            ModificationCommand command)
        {
            Check.NotNull(commandStringBuilder, nameof(commandStringBuilder));
            Check.NotNull(command, nameof(command));

            var name = command.TableName;
            var schema = command.Schema;
            var operations = command.ColumnModifications;

            var writeOperations = operations.Where(o => o.IsWrite).ToArray();
            var conditionOperations = operations.Where(o => o.IsCondition).ToArray();
            var readOperations = operations.Where(o => o.IsRead).ToArray();

            AppendUpdateCommandHeader(commandStringBuilder, name, schema, writeOperations);
            if (readOperations.Length > 0)
            {
                AppendOutputClause(commandStringBuilder, readOperations);
            }
            AppendWhereClause(commandStringBuilder, conditionOperations);
            commandStringBuilder.Append(SqlGenerator.BatchCommandSeparator).AppendLine();

            if (readOperations.Length == 0)
            {
                AppendSelectAffectedCountCommand(commandStringBuilder, name, schema);
            }
        }
        public override void AppendInsertOperation(
            StringBuilder commandStringBuilder,
            ModificationCommand command)
        {
            Check.NotNull(command, nameof(command));

            AppendBulkInsertOperation(commandStringBuilder, new[] { command });
        }
        public override ResultSetMapping AppendInsertOperation(
           StringBuilder commandStringBuilder,
           ModificationCommand command, 
           int commandPosition)
        {
            Check.NotNull(command, nameof(command));

            return AppendBulkInsertOperation(commandStringBuilder, new[] { command }, commandPosition);
        }
        public void AddCommand_does_not_add_command_if_resulting_sql_is_invalid()
        {
            var command = new ModificationCommand("T1", null, new ParameterNameGenerator(), p => p.Relational(), new TypedValueBufferFactoryFactory());

            var batch = new ModificationCommandBatchFake();
            batch.AddCommand(command);
            batch.ShouldAddCommand = true;
            batch.ShouldValidateSql = false;

            batch.AddCommand(command);

            Assert.Equal(1, batch.ModificationCommands.Count);
            Assert.Equal(".", batch.CommandText);
        }
        public void AddCommand_adds_command_if_possible()
        {
            var command = new ModificationCommand("T1", null, new ParameterNameGenerator(), p => p.Relational(), new TypedValueBufferFactoryFactory());

            var batch = new ModificationCommandBatchFake();
            batch.AddCommand(command);
            batch.ShouldAddCommand = true;
            batch.ShouldValidateSql = true;

            batch.AddCommand(command);

            Assert.Equal(2, batch.ModificationCommands.Count);
            Assert.Same(command, batch.ModificationCommands[0]);
            Assert.Equal("..", batch.CommandText);
        }
        public async Task ExecuteAsync_executes_batch_commands_and_consumes_reader()
        {
            var stateEntry = CreateStateEntry(EntityState.Added);
            var command = new ModificationCommand("T1", null, new ParameterNameGenerator());
            command.AddStateEntry(stateEntry);

            var mockReader = CreateDataReaderMock();
            var batch = new ModificationCommandBatchFake(mockReader.Object);
            batch.AddCommand(command, new Mock<SqlGenerator> { CallBase = true }.Object);

            await batch.ExecuteAsync(new Mock<RelationalTransaction>().Object, new RelationalTypeMapper());

            mockReader.Verify(r => r.ReadAsync(It.IsAny<CancellationToken>()), Times.Exactly(1));
            mockReader.Verify(r => r.NextResultAsync(It.IsAny<CancellationToken>()), Times.Once);
        }
        public void GenerateCommandText_compiles_deletes()
        {
            var stateEntry = CreateStateEntry(EntityState.Deleted);

            var command = new ModificationCommand("T1", null, new ParameterNameGenerator());
            command.AddStateEntry(stateEntry);

            var sqlGeneratorMock = new Mock<SqlGenerator>();
            var batch = new ModificationCommandBatchFake();
            batch.AddCommand(command, sqlGeneratorMock.Object);

            batch.GenerateCommandTextBase(sqlGeneratorMock.Object);

            sqlGeneratorMock.Verify(g => g.AppendBatchHeader(It.IsAny<StringBuilder>()));
            sqlGeneratorMock.Verify(g => g.AppendDeleteOperation(It.IsAny<StringBuilder>(), "T1", It.IsAny<IReadOnlyList<ColumnModification>>()));
        }
        public void UpdateCommandText_compiles_inserts()
        {
            var entry = CreateEntry(EntityState.Added);

            var command = new ModificationCommand("T1", null, new ParameterNameGenerator(), p => p.Relational(), new TypedValueBufferFactoryFactory());
            command.AddEntry(entry);

            var sqlGeneratorMock = new Mock<ISqlGenerator>();
            var batch = new ModificationCommandBatchFake(sqlGeneratorMock.Object);
            batch.AddCommand(command);

            batch.UpdateCachedCommandTextBase(0);

            sqlGeneratorMock.Verify(g => g.AppendBatchHeader(It.IsAny<StringBuilder>()));
            sqlGeneratorMock.Verify(g => g.AppendInsertOperation(It.IsAny<StringBuilder>(), command));
        }
        protected override bool CanAddCommand(ModificationCommand modificationCommand)
        {
            if (_maxBatchSize <= ModificationCommands.Count)
            {
                return false;
            }

            var additionalParameterCount = CountParameters(modificationCommand);

            if (_parameterCount + additionalParameterCount >= MaxParameterCount)
            {
                return false;
            }

            _parameterCount += additionalParameterCount;
            return true;
        }
        private int CountParameters(ModificationCommand modificationCommand)
        {
            var parameterCount = 0;
            foreach (var columnModification in modificationCommand.ColumnModifications)
            {
                if (columnModification.ParameterName != null)
                {
                    parameterCount++;
                }

                if (columnModification.OriginalParameterName != null)
                {
                    parameterCount++;
                }
            }

            return parameterCount;
        }
Ejemplo n.º 12
0
        private ModificationCommandBatch StartNewBatch(ParameterNameGenerator parameterNameGenerator, ModificationCommand modificationCommand)
        {
            parameterNameGenerator.Reset();
            var batch = _modificationCommandBatchFactory.Create();

            batch.AddCommand(modificationCommand);
            return(batch);
        }
 protected override bool CanAddCommand(ModificationCommand modificationCommand) => ShouldAddCommand;
Ejemplo n.º 14
0
        /// <summary>
        /// 恢复
        /// </summary>
        /// <param name="relationalReader">关系DataReader</param>
        protected override void Consume(RelationalDataReader relationalReader)
        {
            int commandPosition = 0;
            int rowsAffected    = 0;

            try
            {
                if (Check.IsTraceEnabled(m_oracleLogger?.Logger))
                {
                    Trace <DbLoggerCategory.Update> .Write(m_oracleLogger, LogLevel.Trace, OracleTraceTag.Entry, OracleTraceClassName.OracleModificationCommandBatch, OracleTraceFuncName.Consume);
                }

                while (true)
                {
                    if (commandPosition < CommandResultSet.Count && CommandResultSet[commandPosition] == ResultSetMapping.NoResultSet)
                    {
                        commandPosition++;
                    }
                    else
                    {
                        if (commandPosition < CommandResultSet.Count)
                        {
                            if (ModificationCommands[commandPosition].RequiresResultPropagation)
                            {
                                rowsAffected = 0;
                                do
                                {
                                    ModificationCommand modificationCommand = ModificationCommands[commandPosition];
                                    if (!relationalReader.Read())
                                    {
                                        throw new DbUpdateConcurrencyException(RelationalStrings.UpdateConcurrencyException(ModificationCommands.Count((ModificationCommand m) => m.RequiresResultPropagation), rowsAffected), ModificationCommands[commandPosition].Entries);
                                    }
                                    IRelationalValueBufferFactory relationalValueBufferFactory = CreateValueBufferFactory(modificationCommand.ColumnModifications);
                                    modificationCommand.PropagateResults(relationalValueBufferFactory.Create(relationalReader.DbDataReader));
                                    rowsAffected++;
                                    foreach (ColumnModification columnModification in modificationCommand.ColumnModifications)
                                    {
                                        if (Check.IsTraceEnabled(m_oracleLogger?.Logger))
                                        {
                                            Trace <DbLoggerCategory.Update> .Write(m_oracleLogger, LogLevel.Trace, OracleTraceTag.SQL, OracleTraceClassName.OracleModificationCommandBatch, OracleTraceFuncName.Consume, $"Column Name: {columnModification.ColumnName}");
                                        }
                                    }
                                }while (++commandPosition < CommandResultSet.Count && CommandResultSet[commandPosition - 1] == ResultSetMapping.NotLastInResultSet);
                            }
                            else
                            {
                                int expectedRowsAffected = 1;
                                while (++commandPosition < CommandResultSet.Count && CommandResultSet[commandPosition - 1] == ResultSetMapping.NotLastInResultSet)
                                {
                                    expectedRowsAffected++;
                                }
                                if (!relationalReader.Read())
                                {
                                    break;
                                }
                                rowsAffected = relationalReader.DbDataReader.GetInt32(0);
                                if (rowsAffected != expectedRowsAffected)
                                {
                                    throw new DbUpdateConcurrencyException(RelationalStrings.UpdateConcurrencyException(expectedRowsAffected, rowsAffected), ModificationCommands[commandPosition - 1].Entries);
                                }
                            }
                        }
                        if (commandPosition >= CommandResultSet.Count || !relationalReader.DbDataReader.NextResult())
                        {
                            return;
                        }
                    }
                }
                throw new DbUpdateConcurrencyException(RelationalStrings.UpdateConcurrencyException(1, 0), ModificationCommands[commandPosition - 1].Entries);
            }
            catch (DbUpdateException dbEx)
            {
                if (Check.IsErrorEnabled(m_oracleLogger?.Logger))
                {
                    Trace <DbLoggerCategory.Update> .Write(m_oracleLogger, LogLevel.Error, OracleTraceTag.Error, OracleTraceClassName.OracleModificationCommandBatch, OracleTraceFuncName.Consume, dbEx.ToString());
                }
                throw;
            }
            catch (Exception ex)
            {
                if (Check.IsErrorEnabled(m_oracleLogger?.Logger))
                {
                    Trace <DbLoggerCategory.Update> .Write(m_oracleLogger, LogLevel.Error, OracleTraceTag.Error, OracleTraceClassName.OracleModificationCommandBatch, OracleTraceFuncName.Consume, ex.ToString());
                }
                throw new DbUpdateException(RelationalStrings.UpdateStoreException, ex, ModificationCommands[commandPosition - 1].Entries);
            }
        }
Ejemplo n.º 15
0
        public void Compare_returns_0_only_for_commands_that_are_equal()
        {
            var model      = new Entity.Metadata.Model();
            var entityType = model.AddEntityType(typeof(object));

            var optionsBuilder = new EntityOptionsBuilder()
                                 .UseModel(model);

            optionsBuilder.UseInMemoryStore(persist: false);

            var contextServices = ((IAccessor <IServiceProvider>) new DbContext(optionsBuilder.Options)).Service;
            var stateManager    = contextServices.GetRequiredService <IStateManager>();

            var key = entityType.GetOrAddProperty("Id", typeof(int), shadowProperty: true);

            entityType.GetOrSetPrimaryKey(key);

            var entry1 = stateManager.GetOrCreateEntry(new object());

            entry1[key] = 1;
            entry1.SetEntityState(EntityState.Added);
            var modificationCommandAdded = new ModificationCommand("A", null, new ParameterNameGenerator(), p => p.Relational(), new UntypedValueBufferFactoryFactory());

            modificationCommandAdded.AddEntry(entry1);

            var entry2 = stateManager.GetOrCreateEntry(new object());

            entry2[key] = 2;
            entry2.SetEntityState(EntityState.Modified);
            var modificationCommandModified = new ModificationCommand("A", null, new ParameterNameGenerator(), p => p.Relational(), new UntypedValueBufferFactoryFactory());

            modificationCommandModified.AddEntry(entry2);

            var entry3 = stateManager.GetOrCreateEntry(new object());

            entry3[key] = 3;
            entry3.SetEntityState(EntityState.Deleted);
            var modificationCommandDeleted = new ModificationCommand("A", null, new ParameterNameGenerator(), p => p.Relational(), new UntypedValueBufferFactoryFactory());

            modificationCommandDeleted.AddEntry(entry3);

            var mCC = new ModificationCommandComparer();

            Assert.True(0 == mCC.Compare(modificationCommandAdded, modificationCommandAdded));
            Assert.True(0 == mCC.Compare(null, null));
            Assert.True(0 == mCC.Compare(
                            new ModificationCommand("A", "dbo", new ParameterNameGenerator(), p => p.Relational(), new UntypedValueBufferFactoryFactory()),
                            new ModificationCommand("A", "dbo", new ParameterNameGenerator(), p => p.Relational(), new UntypedValueBufferFactoryFactory())));

            Assert.True(0 > mCC.Compare(null, new ModificationCommand("A", null, new ParameterNameGenerator(), p => p.Relational(), new UntypedValueBufferFactoryFactory())));
            Assert.True(0 < mCC.Compare(new ModificationCommand("A", null, new ParameterNameGenerator(), p => p.Relational(), new UntypedValueBufferFactoryFactory()), null));

            Assert.True(0 > mCC.Compare(
                            new ModificationCommand("A", null, new ParameterNameGenerator(), p => p.Relational(), new UntypedValueBufferFactoryFactory()),
                            new ModificationCommand("A", "dbo", new ParameterNameGenerator(), p => p.Relational(), new UntypedValueBufferFactoryFactory())));
            Assert.True(0 < mCC.Compare(
                            new ModificationCommand("A", "dbo", new ParameterNameGenerator(), p => p.Relational(), new UntypedValueBufferFactoryFactory()),
                            new ModificationCommand("A", null, new ParameterNameGenerator(), p => p.Relational(), new UntypedValueBufferFactoryFactory())));

            Assert.True(0 > mCC.Compare(
                            new ModificationCommand("A", "dbo", new ParameterNameGenerator(), p => p.Relational(), new UntypedValueBufferFactoryFactory()),
                            new ModificationCommand("A", "foo", new ParameterNameGenerator(), p => p.Relational(), new UntypedValueBufferFactoryFactory())));
            Assert.True(0 < mCC.Compare(
                            new ModificationCommand("A", "foo", new ParameterNameGenerator(), p => p.Relational(), new UntypedValueBufferFactoryFactory()),
                            new ModificationCommand("A", "dbo", new ParameterNameGenerator(), p => p.Relational(), new UntypedValueBufferFactoryFactory())));

            Assert.True(0 > mCC.Compare(
                            new ModificationCommand("A", null, new ParameterNameGenerator(), p => p.Relational(), new UntypedValueBufferFactoryFactory()),
                            new ModificationCommand("B", null, new ParameterNameGenerator(), p => p.Relational(), new UntypedValueBufferFactoryFactory())));
            Assert.True(0 < mCC.Compare(
                            new ModificationCommand("B", null, new ParameterNameGenerator(), p => p.Relational(), new UntypedValueBufferFactoryFactory()),
                            new ModificationCommand("A", null, new ParameterNameGenerator(), p => p.Relational(), new UntypedValueBufferFactoryFactory())));

            Assert.True(0 > mCC.Compare(modificationCommandModified, modificationCommandAdded));
            Assert.True(0 < mCC.Compare(modificationCommandAdded, modificationCommandModified));

            Assert.True(0 > mCC.Compare(modificationCommandDeleted, modificationCommandAdded));
            Assert.True(0 < mCC.Compare(modificationCommandAdded, modificationCommandDeleted));

            Assert.True(0 > mCC.Compare(modificationCommandDeleted, modificationCommandModified));
            Assert.True(0 < mCC.Compare(modificationCommandModified, modificationCommandDeleted));
        }
Ejemplo n.º 16
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>
        protected virtual IEnumerable <ModificationCommand> CreateModificationCommands(
            IList <IUpdateEntry> entries,
            IUpdateAdapter updateAdapter,
            Func <string> generateParameterName)
        {
            var commands = new List <ModificationCommand>();
            Dictionary <(string Name, string?Schema), SharedTableEntryMap <ModificationCommand> >?sharedTablesCommandsMap =
                null;

            foreach (var entry in entries)
            {
                if (entry.SharedIdentityEntry != null &&
                    entry.EntityState == EntityState.Deleted)
                {
                    continue;
                }

                var mappings     = (IReadOnlyCollection <ITableMapping>)entry.EntityType.GetTableMappings();
                var mappingCount = mappings.Count;
                ModificationCommand?firstCommand = null;
                foreach (var mapping in mappings)
                {
                    var table    = mapping.Table;
                    var tableKey = (table.Name, table.Schema);

                    ModificationCommand command;
                    var isMainEntry = true;
                    if (table.IsShared)
                    {
                        if (sharedTablesCommandsMap == null)
                        {
                            sharedTablesCommandsMap = new Dictionary <(string, string?), SharedTableEntryMap <ModificationCommand> >();
                        }

                        if (!sharedTablesCommandsMap.TryGetValue(tableKey, out var sharedCommandsMap))
                        {
                            sharedCommandsMap = new SharedTableEntryMap <ModificationCommand>(table, updateAdapter);
                            sharedTablesCommandsMap.Add(tableKey, sharedCommandsMap);
                        }

                        command = sharedCommandsMap.GetOrAddValue(
                            entry,
                            (n, s, c) => new ModificationCommand(n, s, generateParameterName, _sensitiveLoggingEnabled, c, Dependencies.UpdateLogger));
                        isMainEntry = sharedCommandsMap.IsMainEntry(entry);
                    }
                    else
                    {
                        command = new ModificationCommand(
                            table.Name, table.Schema, generateParameterName, _sensitiveLoggingEnabled, comparer: null, Dependencies.UpdateLogger);
                    }

                    command.AddEntry(entry, isMainEntry);
                    commands.Add(command);

                    if (firstCommand == null)
                    {
                        Check.DebugAssert(firstCommand == null, "firstCommand == null");
                        firstCommand = command;
                    }
                }

                if (firstCommand == null)
                {
                    throw new InvalidOperationException(RelationalStrings.ReadonlyEntitySaved(entry.EntityType.DisplayName()));
                }
            }

            if (sharedTablesCommandsMap != null)
            {
                AddUnchangedSharingEntries(sharedTablesCommandsMap.Values, entries);
            }

            return(commands);
        }
        public void UpdateCommandText_compiles_multiple_commands()
        {
            var entry = CreateEntry(EntityState.Added);

            var command = new ModificationCommand("T1", null, new ParameterNameGenerator(), p => p.Relational(), new TypedValueBufferFactoryFactory());
            command.AddEntry(entry);

            var fakeSqlGenerator = new FakeSqlGenerator();
            var batch = new ModificationCommandBatchFake(fakeSqlGenerator);
            batch.AddCommand(command);
            batch.AddCommand(command);

            Assert.Equal("..", batch.CommandText);

            Assert.Equal(1, fakeSqlGenerator.AppendBatchHeaderCalls);
        }
        public async Task ExecuteAsync_executes_batch_commands_and_consumes_reader()
        {
            var entry = CreateEntry(EntityState.Added);
            var command = new ModificationCommand("T1", null, new ParameterNameGenerator(), p => p.Relational(), new TypedValueBufferFactoryFactory());
            command.AddEntry(entry);

            var mockReader = CreateDataReaderMock();
            var batch = new ModificationCommandBatchFake(mockReader.Object);
            batch.AddCommand(command);

            var transactionMock = new Mock<RelationalTransaction>(
                Mock.Of<IRelationalConnection>(), Mock.Of<DbTransaction>(), false, Mock.Of<ILogger>());

            await batch.ExecuteAsync(transactionMock.Object, new RelationalTypeMapper(), new Mock<DbContext>().Object, new Mock<ILogger>().Object);

            mockReader.Verify(r => r.ReadAsync(It.IsAny<CancellationToken>()), Times.Once);
            mockReader.Verify(r => r.GetInt32(0), Times.Once);
        }
Ejemplo n.º 19
0
        public override ResultSetMapping AppendUpdateOperation(StringBuilder commandStringBuilder, ModificationCommand command, int commandPosition)
        {
            Check.NotNull(commandStringBuilder, nameof(commandStringBuilder));
            Check.NotNull(command, nameof(command));

            var name       = command.TableName;
            var schema     = command.Schema;
            var operations = command.ColumnModifications;

            var writeOperations     = operations.Where(o => o.IsWrite).ToArray();
            var conditionOperations = operations.Where(o => o.IsCondition).ToArray();
            var readOperations      = operations.Where(o => o.IsRead).ToArray();

            if (readOperations.Length > 0)
            {
                AppendDeclareTable(commandStringBuilder, "@inserted" + commandPosition, readOperations);
            }
            AppendUpdateCommandHeader(commandStringBuilder, name, schema, writeOperations);
            if (readOperations.Length > 0)
            {
                AppendOutputClause(commandStringBuilder, readOperations, "@inserted" + commandPosition);
            }
            AppendWhereClause(commandStringBuilder, conditionOperations);
            commandStringBuilder.Append(SqlGenerationHelper.StatementTerminator);

            if (readOperations.Length > 0)
            {
                return(AppendSelectCommand(commandStringBuilder, readOperations, "@inserted" + commandPosition));
            }
            commandStringBuilder.AppendLine();

            return(AppendSelectAffectedCountCommand(commandStringBuilder, name, schema, commandPosition));
        }
        public async Task ExecuteAsync_saves_store_generated_values_when_updating()
        {
            var entry = CreateEntry(
                EntityState.Modified, generateKeyValues: true, computeNonKeyValue: true);

            var command = new ModificationCommand("T1", null, new ParameterNameGenerator(), p => p.Relational(), new TypedValueBufferFactoryFactory());
            command.AddEntry(entry);

            var batch = new ModificationCommandBatchFake(CreateDataReaderMock(new[] { "Col2" }, new List<object[]> { new object[] { "FortyTwo" } }).Object);
            batch.AddCommand(command);

            var transactionMock = new Mock<RelationalTransaction>(
                Mock.Of<IRelationalConnection>(), Mock.Of<DbTransaction>(), false, Mock.Of<ILogger>());

            await batch.ExecuteAsync(transactionMock.Object, new RelationalTypeMapper(), new Mock<DbContext>().Object, new Mock<ILogger>().Object);

            Assert.Equal(1, entry[entry.EntityType.GetProperty("Id")]);
            Assert.Equal("FortyTwo", entry[entry.EntityType.GetProperty("Name")]);
        }
        public async Task ExecuteAsync_saves_store_generated_values()
        {
            var stateEntry = CreateStateEntry(EntityState.Added, ValueGenerationOnSave.WhenInserting);
            var command = new ModificationCommand("T1", null, new ParameterNameGenerator());
            command.AddStateEntry(stateEntry);

            var batch = new ModificationCommandBatchFake(CreateDataReaderMock(new[] { "Col1" }, new List<object[]> { new object[] { 42 } }).Object);
            batch.AddCommand(command, new Mock<SqlGenerator> { CallBase = true }.Object);

            await batch.ExecuteAsync(new Mock<RelationalTransaction>().Object, new RelationalTypeMapper());

            Assert.Equal(42, stateEntry[stateEntry.EntityType.GetProperty("Id")]);
            Assert.Equal("Test", stateEntry[stateEntry.EntityType.GetProperty("Name")]);
        }
        public async Task Exception_not_thrown_for_more_than_one_row_returned_for_single_command()
        {
            var entry = CreateEntry(EntityState.Added, generateKeyValues: true);
            entry.MarkAsTemporary(entry.EntityType.GetPrimaryKey().Properties[0]);

            var command = new ModificationCommand("T1", null, new ParameterNameGenerator(), p => p.Relational(), new TypedValueBufferFactoryFactory());
            command.AddEntry(entry);

            var mockReader = CreateDataReaderMock(new[] { "Col1" }, new List<object[]>
                {
                    new object[] { 42 },
                    new object[] { 43 }
                });
            var batch = new ModificationCommandBatchFake(mockReader.Object);
            batch.AddCommand(command);

            var transactionMock = new Mock<RelationalTransaction>(
                Mock.Of<IRelationalConnection>(), Mock.Of<DbTransaction>(), false, Mock.Of<ILogger>());

            await batch.ExecuteAsync(transactionMock.Object, new RelationalTypeMapper(), new Mock<DbContext>().Object, new Mock<ILogger>().Object);

            Assert.Equal(42, entry[entry.EntityType.GetProperty("Id")]);
        }
        public async Task Exception_thrown_if_no_rows_returned_for_command_with_store_generated_values()
        {
            var stateEntry = CreateStateEntry(EntityState.Added, ValueGenerationOnSave.WhenInserting);
            var command = new ModificationCommand("T1", null, new ParameterNameGenerator());
            command.AddStateEntry(stateEntry);

            var batch = new ModificationCommandBatchFake(CreateDataReaderMock(new[] { "Col1" }, new List<object[]>()).Object);
            batch.AddCommand(command, new Mock<SqlGenerator> { CallBase = true }.Object);

            Assert.Equal(Strings.FormatUpdateConcurrencyException(1, 0),
                (await Assert.ThrowsAsync<DbUpdateConcurrencyException>(
                    async () => await batch.ExecuteAsync(new Mock<RelationalTransaction>().Object, new RelationalTypeMapper()))).Message);
        }
        public async Task Exception_not_thrown_for_more_than_one_row_returned_for_single_command()
        {
            var stateEntry = CreateStateEntry(EntityState.Added, ValueGenerationOnSave.WhenInserting);
            var command = new ModificationCommand("T1", null, new ParameterNameGenerator());
            command.AddStateEntry(stateEntry);

            var mockReader = CreateDataReaderMock(new[] { "Col1" }, new List<object[]>
                {
                    new object[] { 42 },
                    new object[] { 43 }
                });
            var batch = new ModificationCommandBatchFake(mockReader.Object);
            batch.AddCommand(command, new Mock<SqlGenerator> { CallBase = true }.Object);

            await batch.ExecuteAsync(new Mock<RelationalTransaction>().Object, new RelationalTypeMapper());

            Assert.Equal(42, stateEntry[stateEntry.EntityType.GetProperty("Id")]);
        }
Ejemplo n.º 25
0
 protected override bool CanAddCommand(ModificationCommand modificationCommand)
 {
     // TODO: check this
     return(true);
 }
        public override ResultSetMapping AppendUpdateOperation(StringBuilder commandStringBuilder, ModificationCommand command, int commandPosition)
        {
            Check.NotNull(commandStringBuilder, nameof(commandStringBuilder));
            Check.NotNull(command, nameof(command));

            var name = command.TableName;
            var schema = command.Schema;
            var operations = command.ColumnModifications;

            var writeOperations = operations.Where(o => o.IsWrite).ToArray();
            var conditionOperations = operations.Where(o => o.IsCondition).ToArray();
            var readOperations = operations.Where(o => o.IsRead).ToArray();

            if (readOperations.Length > 0)
            {
                AppendDeclareTable(commandStringBuilder, InsertedTableBaseName, commandPosition, readOperations);
            }
            AppendUpdateCommandHeader(commandStringBuilder, name, schema, writeOperations);
            if (readOperations.Length > 0)
            {
                AppendOutputClause(commandStringBuilder, readOperations, InsertedTableBaseName, commandPosition);
            }
            AppendWhereClause(commandStringBuilder, conditionOperations);
            commandStringBuilder.Append(SqlGenerationHelper.StatementTerminator);

            if (readOperations.Length > 0)
            {
                return AppendSelectCommand(commandStringBuilder, readOperations, InsertedTableBaseName, commandPosition);
            }
            commandStringBuilder.AppendLine();

            return AppendSelectAffectedCountCommand(commandStringBuilder, name, schema, commandPosition);
        }
Ejemplo n.º 27
0
        public virtual void AppendUpdateOperation(StringBuilder commandStringBuilder, ModificationCommand command)
        {
            Check.NotNull(command, nameof(command));

            var tableName  = command.TableName;
            var schemaName = command.SchemaName;
            var operations = command.ColumnModifications;

            var writeOperations     = operations.Where(o => o.IsWrite).ToArray();
            var conditionOperations = operations.Where(o => o.IsCondition).ToArray();
            var readOperations      = operations.Where(o => o.IsRead).ToArray();

            AppendUpdateCommand(commandStringBuilder, tableName, schemaName, writeOperations, conditionOperations);

            if (readOperations.Length > 0)
            {
                var keyOperations = operations.Where(o => o.IsKey).ToArray();

                AppendSelectAffectedCommand(commandStringBuilder, tableName, schemaName, readOperations, keyOperations);
            }
            else
            {
                AppendSelectAffectedCountCommand(commandStringBuilder, tableName, schemaName);
            }
        }
 private static void AddMatchingPredecessorEdge(
     Dictionary<IKeyValueIndex, List<ModificationCommand>> predecessorsMap,
     IKeyValueIndex dependentKeyValue,
     Multigraph<ModificationCommand, IForeignKey> commandGraph,
     ModificationCommand command,
     IForeignKey foreignKey)
 {
     List<ModificationCommand> predecessorCommands;
     if (predecessorsMap.TryGetValue(dependentKeyValue, out predecessorCommands))
     {
         foreach (var predecessor in predecessorCommands)
         {
             if (predecessor != command)
             {
                 commandGraph.AddEdge(predecessor, command, foreignKey);
             }
         }
     }
 }
 public override void AppendInsertOperation(StringBuilder commandStringBuilder, ModificationCommand command)
 {
     if (AppendInsertOperationCallback != null)
     {
         AppendInsertOperationCallback(commandStringBuilder, command);
     }
 }
        /// <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>
        protected virtual IEnumerable<ModificationCommand> CreateModificationCommands(
            [NotNull] IReadOnlyList<IUpdateEntry> entries,
            [NotNull] Func<string> generateParameterName)
        {
            // TODO: Handle multiple state entries that update the same row

            Func<IProperty, IRelationalPropertyAnnotations> getAnnotationsDelegate = _annotationProvider.For;
            foreach (var entry in entries)
            {
                var command = new ModificationCommand(
                    _annotationProvider.For(entry.EntityType).TableName,
                    _annotationProvider.For(entry.EntityType).Schema,
                    generateParameterName,
                    getAnnotationsDelegate);

                command.AddEntry(entry);
                if (command.EntityState != EntityState.Modified
                    || command.ColumnModifications.Any(m => m.IsWrite))
                {
                    yield return command;
                }
            }
        }
Ejemplo n.º 31
0
        private void Format(IForeignKey foreignKey, ModificationCommand source, ModificationCommand target, StringBuilder builder)
        {
            var reverseDependency = !source.Entries.Any(e => foreignKey.DeclaringEntityType.IsAssignableFrom(e.EntityType));

            if (reverseDependency)
            {
                builder.Append(" <-");
            }

            builder.Append(" ");
            if (foreignKey.DependentToPrincipal != null ||
                foreignKey.PrincipalToDependent != null)
            {
                if (!reverseDependency &&
                    foreignKey.DependentToPrincipal != null)
                {
                    builder.Append(foreignKey.DependentToPrincipal.Name);
                    builder.Append(" ");
                }

                if (foreignKey.PrincipalToDependent != null)
                {
                    builder.Append(foreignKey.PrincipalToDependent.Name);
                    builder.Append(" ");
                }

                if (reverseDependency &&
                    foreignKey.DependentToPrincipal != null)
                {
                    builder.Append(foreignKey.DependentToPrincipal.Name);
                    builder.Append(" ");
                }
            }
            else
            {
                builder.Append("ForeignKey ");
            }

            var dependentCommand = reverseDependency ? target : source;
            var dependentEntry   = dependentCommand.Entries.First(e => foreignKey.DeclaringEntityType.IsAssignableFrom(e.EntityType));

            builder.Append("{ ");
            for (var i = 0; i < foreignKey.Properties.Count; i++)
            {
                var property = foreignKey.Properties[i];
                builder.Append("'");
                builder.Append(property.Name);
                builder.Append("'");
                if (_sensitiveLoggingEnabled)
                {
                    builder.Append(": ");
                    builder.Append(dependentEntry.GetCurrentValue(property));
                }

                if (i != foreignKey.Properties.Count - 1)
                {
                    builder.Append(", ");
                }
            }

            builder.Append(" } ");

            if (!reverseDependency)
            {
                builder.Append("<- ");
            }
        }
Ejemplo n.º 32
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>
 protected override bool CanAddCommand(ModificationCommand modificationCommand)
 {
     return(ModificationCommands.Count == 0);
 }
        public async Task Exception_thrown_if_no_rows_returned_for_command_with_store_generated_values()
        {
            var entry = CreateEntry(EntityState.Added, generateKeyValues: true);
            entry.MarkAsTemporary(entry.EntityType.GetPrimaryKey().Properties[0]);

            var command = new ModificationCommand("T1", null, new ParameterNameGenerator(), p => p.Relational(), new TypedValueBufferFactoryFactory());
            command.AddEntry(entry);

            var batch = new ModificationCommandBatchFake(CreateDataReaderMock(new[] { "Col1" }, new List<object[]>()).Object);
            batch.AddCommand(command);

            var transactionMock = new Mock<RelationalTransaction>(
                Mock.Of<IRelationalConnection>(), Mock.Of<DbTransaction>(), false, Mock.Of<ILogger>());

            Assert.Equal(Strings.UpdateConcurrencyException(1, 0),
                (await Assert.ThrowsAsync<DbUpdateConcurrencyException>(
                    async () => await batch.ExecuteAsync(
                        transactionMock.Object,
                        new RelationalTypeMapper(),
                        new Mock<DbContext>().Object,
                        new Mock<ILogger>().Object))).Message);
        }
 protected override bool CanAddCommand(ModificationCommand modificationCommand)
 => ModificationCommands.Count == 0;
Ejemplo n.º 35
0
        /// <summary>
        /// 异步恢复
        /// </summary>
        /// <param name="relationalReader">关系DataReader</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns></returns>
        protected override async Task ConsumeAsync(RelationalDataReader relationalReader, CancellationToken cancellationToken = default(CancellationToken))
        {
            int commandPosition = 0;

            try
            {
                if (Check.IsTraceEnabled(m_oracleLogger?.Logger))
                {
                    Trace <DbLoggerCategory.Update> .Write(m_oracleLogger, LogLevel.Trace, OracleTraceTag.Entry, OracleTraceClassName.OracleModificationCommandBatch, OracleTraceFuncName.ConsumeAsync);
                }

                while (true)
                {
                    if (commandPosition < CommandResultSet.Count && CommandResultSet[commandPosition] == ResultSetMapping.NoResultSet)
                    {
                        commandPosition++;
                    }
                    else
                    {
                        if (commandPosition < CommandResultSet.Count)
                        {
                            if (ModificationCommands[commandPosition].RequiresResultPropagation)
                            {
                                int rowsAffected = 0;
                                int num          = 0;
                                do
                                {
                                    ModificationCommand tableModification = ModificationCommands[commandPosition];
                                    if (!(await relationalReader.ReadAsync(cancellationToken)))
                                    {
                                        throw new DbUpdateConcurrencyException(RelationalStrings.UpdateConcurrencyException(ModificationCommands.Count((ModificationCommand m) => m.RequiresResultPropagation), rowsAffected), ModificationCommands[commandPosition].Entries);
                                    }
                                    IRelationalValueBufferFactory relationalValueBufferFactory = CreateValueBufferFactory(tableModification.ColumnModifications);
                                    tableModification.PropagateResults(relationalValueBufferFactory.Create(relationalReader.DbDataReader));
                                    rowsAffected++;
                                    num             = commandPosition + 1;
                                    commandPosition = num;
                                }while (num < CommandResultSet.Count && CommandResultSet[commandPosition - 1] == ResultSetMapping.NotLastInResultSet);
                            }
                            else
                            {
                                int expectedRowsAffected = 1;
                                while (true)
                                {
                                    int num = commandPosition + 1;
                                    commandPosition = num;
                                    if (num >= CommandResultSet.Count || CommandResultSet[commandPosition - 1] != ResultSetMapping.NotLastInResultSet)
                                    {
                                        break;
                                    }
                                    expectedRowsAffected++;
                                }
                                if (!relationalReader.Read())
                                {
                                    break;
                                }
                                int rowsAffected = relationalReader.DbDataReader.GetInt32(0);
                                if (rowsAffected != expectedRowsAffected)
                                {
                                    throw new DbUpdateConcurrencyException(RelationalStrings.UpdateConcurrencyException(expectedRowsAffected, rowsAffected), ModificationCommands[commandPosition - 1].Entries);
                                }
                            }
                        }
                        bool flag = commandPosition < CommandResultSet.Count;
                        if (flag)
                        {
                            flag = await relationalReader.DbDataReader.NextResultAsync(cancellationToken);
                        }
                        if (!flag)
                        {
                            return;
                        }
                    }
                }
                throw new DbUpdateConcurrencyException(RelationalStrings.UpdateConcurrencyException(1, 0), ModificationCommands[commandPosition - 1].Entries);
            }
            catch (DbUpdateException dbEx)
            {
                if (Check.IsErrorEnabled(m_oracleLogger?.Logger))
                {
                    Trace <DbLoggerCategory.Update> .Write(m_oracleLogger, LogLevel.Error, OracleTraceTag.Error, OracleTraceClassName.OracleModificationCommandBatch, OracleTraceFuncName.ConsumeAsync, dbEx.ToString());
                }
                throw;
            }
            catch (Exception ex)
            {
                if (Check.IsErrorEnabled(m_oracleLogger?.Logger))
                {
                    Trace <DbLoggerCategory.Update> .Write(m_oracleLogger, LogLevel.Error, OracleTraceTag.Error, OracleTraceClassName.OracleModificationCommandBatch, OracleTraceFuncName.ConsumeAsync, ex.ToString());
                }
                throw new DbUpdateException(RelationalStrings.UpdateStoreException, ex, ModificationCommands[commandPosition].Entries);
            }
        }
Ejemplo n.º 36
0
        public void Compare_returns_0_only_for_commands_that_are_equal()
        {
            var model      = new Model();
            var entityType = model.AddEntityType(typeof(object));

            var optionsBuilder = new DbContextOptionsBuilder()
                                 .UseModel(model);

            optionsBuilder.UseInMemoryDatabase();

            var contextServices = new DbContext(optionsBuilder.Options).GetInfrastructure();
            var stateManager    = contextServices.GetRequiredService <IStateManager>();

            var key = entityType.AddProperty("Id", typeof(int));

            entityType.GetOrSetPrimaryKey(key);

            var entry1 = stateManager.GetOrCreateEntry(new object());

            entry1[key] = 1;
            entry1.SetEntityState(EntityState.Added);
            var modificationCommandAdded = new ModificationCommand("A", null, new ParameterNameGenerator().GenerateNext, p => p.TestProvider());

            modificationCommandAdded.AddEntry(entry1);

            var entry2 = stateManager.GetOrCreateEntry(new object());

            entry2[key] = 2;
            entry2.SetEntityState(EntityState.Modified);
            var modificationCommandModified = new ModificationCommand("A", null, new ParameterNameGenerator().GenerateNext, p => p.TestProvider());

            modificationCommandModified.AddEntry(entry2);

            var entry3 = stateManager.GetOrCreateEntry(new object());

            entry3[key] = 3;
            entry3.SetEntityState(EntityState.Deleted);
            var modificationCommandDeleted = new ModificationCommand("A", null, new ParameterNameGenerator().GenerateNext, p => p.TestProvider());

            modificationCommandDeleted.AddEntry(entry3);

            var mCC = new ModificationCommandComparer();

            Assert.True(0 == mCC.Compare(modificationCommandAdded, modificationCommandAdded));
            Assert.True(0 == mCC.Compare(null, null));
            Assert.True(0 == mCC.Compare(
                            new ModificationCommand("A", "dbo", new ParameterNameGenerator().GenerateNext, p => p.TestProvider()),
                            new ModificationCommand("A", "dbo", new ParameterNameGenerator().GenerateNext, p => p.TestProvider())));

            Assert.True(0 > mCC.Compare(null, new ModificationCommand("A", null, new ParameterNameGenerator().GenerateNext, p => p.TestProvider())));
            Assert.True(0 < mCC.Compare(new ModificationCommand("A", null, new ParameterNameGenerator().GenerateNext, p => p.TestProvider()), null));

            Assert.True(0 > mCC.Compare(
                            new ModificationCommand("A", null, new ParameterNameGenerator().GenerateNext, p => p.TestProvider()),
                            new ModificationCommand("A", "dbo", new ParameterNameGenerator().GenerateNext, p => p.TestProvider())));
            Assert.True(0 < mCC.Compare(
                            new ModificationCommand("A", "dbo", new ParameterNameGenerator().GenerateNext, p => p.TestProvider()),
                            new ModificationCommand("A", null, new ParameterNameGenerator().GenerateNext, p => p.TestProvider())));

            Assert.True(0 > mCC.Compare(
                            new ModificationCommand("A", "dbo", new ParameterNameGenerator().GenerateNext, p => p.TestProvider()),
                            new ModificationCommand("A", "foo", new ParameterNameGenerator().GenerateNext, p => p.TestProvider())));
            Assert.True(0 < mCC.Compare(
                            new ModificationCommand("A", "foo", new ParameterNameGenerator().GenerateNext, p => p.TestProvider()),
                            new ModificationCommand("A", "dbo", new ParameterNameGenerator().GenerateNext, p => p.TestProvider())));

            Assert.True(0 > mCC.Compare(
                            new ModificationCommand("A", null, new ParameterNameGenerator().GenerateNext, p => p.TestProvider()),
                            new ModificationCommand("B", null, new ParameterNameGenerator().GenerateNext, p => p.TestProvider())));
            Assert.True(0 < mCC.Compare(
                            new ModificationCommand("B", null, new ParameterNameGenerator().GenerateNext, p => p.TestProvider()),
                            new ModificationCommand("A", null, new ParameterNameGenerator().GenerateNext, p => p.TestProvider())));

            Assert.True(0 > mCC.Compare(modificationCommandModified, modificationCommandAdded));
            Assert.True(0 < mCC.Compare(modificationCommandAdded, modificationCommandModified));

            Assert.True(0 > mCC.Compare(modificationCommandDeleted, modificationCommandAdded));
            Assert.True(0 < mCC.Compare(modificationCommandAdded, modificationCommandDeleted));

            Assert.True(0 > mCC.Compare(modificationCommandDeleted, modificationCommandModified));
            Assert.True(0 < mCC.Compare(modificationCommandModified, modificationCommandDeleted));
        }
Ejemplo n.º 37
0
 public override ResultSetMapping AppendInsertOperation(
     StringBuilder commandStringBuilder,
     ModificationCommand command,
     int commandPosition)
 => AppendInsertOperation(commandStringBuilder, command, commandPosition, false);
Ejemplo n.º 38
0
        public override ResultSetMapping AppendDeleteOperation(StringBuilder commandStringBuilder, ModificationCommand command, int commandPosition)
        {
            var sqlGenerationHelper = (IFbSqlGenerationHelper)SqlGenerationHelper;
            var name                = command.TableName;
            var operations          = command.ColumnModifications;
            var conditionOperations = operations.Where(o => o.IsCondition).ToList();
            var inputOperations     = conditionOperations;

            commandStringBuilder.Append("EXECUTE BLOCK (");
            commandStringBuilder.AppendJoin(inputOperations, (b, e) =>
            {
                var type          = GetColumnType(e);
                var parameterName = e.UseOriginalValueParameter
                    ? e.OriginalParameterName
                    : e.ParameterName;
                b.Append(parameterName);
                b.Append(" ");
                b.Append(type);
                b.Append(" = ?");
            }, ", ");
            commandStringBuilder.AppendLine(")");
            commandStringBuilder.AppendLine($"RETURNS (RowsAffected {_typeReturn})");
            commandStringBuilder.AppendLine("AS");
            commandStringBuilder.AppendLine("BEGIN");
            var oldParameterNameMarker = sqlGenerationHelper.ParameterName;

            sqlGenerationHelper.ParameterName = ":";
            try
            {
                AppendDeleteCommandHeader(commandStringBuilder, name, null);
                AppendWhereClause(commandStringBuilder, conditionOperations);
            }
            finally
            {
                sqlGenerationHelper.ParameterName = oldParameterNameMarker;
            }
            commandStringBuilder
            .Append(SqlGenerationHelper.StatementTerminator)
            .AppendLine();
            commandStringBuilder.AppendLine();
            commandStringBuilder.AppendLine("RowsAffected = ROW_COUNT;");
            commandStringBuilder.AppendLine("SUSPEND;");
            commandStringBuilder.Append("END");
            commandStringBuilder
            .Append(SqlGenerationHelper.StatementTerminator)
            .AppendLine();
            return(ResultSetMapping.LastInResultSet);
        }
            public override ResultSetMapping AppendInsertOperation(StringBuilder commandStringBuilder, ModificationCommand command, int commandPosition)
            {
                if (!string.IsNullOrEmpty(command.Schema))
                {
                    commandStringBuilder.Append(command.Schema + ".");
                }
                commandStringBuilder.Append(command.TableName);

                return(ResultSetMapping.NotLastInResultSet);
            }
Ejemplo n.º 40
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>
        protected virtual IEnumerable <ModificationCommand> CreateModificationCommands(
            [NotNull] IList <IUpdateEntry> entries,
            [NotNull] Func <string> generateParameterName)
        {
            var commands = new List <ModificationCommand>();

            if (_sharedTableEntryMapFactories == null)
            {
                _sharedTableEntryMapFactories = SharedTableEntryMap <ModificationCommand>
                                                .CreateSharedTableEntryMapFactories(entries[0].EntityType.Model, StateManager);
            }

            Dictionary <(string Schema, string Name), SharedTableEntryMap <ModificationCommand> > sharedTablesCommandsMap =
                null;

            foreach (var entry in entries)
            {
                if (entry.SharedIdentityEntry != null &&
                    entry.EntityState == EntityState.Deleted)
                {
                    continue;
                }

                var entityType           = entry.EntityType;
                var relationalExtensions = entityType.Relational();
                var table    = relationalExtensions.TableName;
                var schema   = relationalExtensions.Schema;
                var tableKey = (schema, table);

                ModificationCommand command;
                if (_sharedTableEntryMapFactories.TryGetValue(tableKey, out var commandIdentityMapFactory))
                {
                    if (sharedTablesCommandsMap == null)
                    {
                        sharedTablesCommandsMap =
                            new Dictionary <(string Schema, string Name), SharedTableEntryMap <ModificationCommand> >();
                    }

                    if (!sharedTablesCommandsMap.TryGetValue(tableKey, out var sharedCommandsMap))
                    {
                        sharedCommandsMap = commandIdentityMapFactory(
                            (t, s, c) => new ModificationCommand(
                                t, s, generateParameterName, _sensitiveLoggingEnabled, c));
                        sharedTablesCommandsMap.Add((schema, table), sharedCommandsMap);
                    }

                    command = sharedCommandsMap.GetOrAddValue(entry);
                }
                else
                {
                    command = new ModificationCommand(
                        table, schema, generateParameterName, _sensitiveLoggingEnabled, comparer: null);
                }

                command.AddEntry(entry);
                commands.Add(command);
            }

            if (sharedTablesCommandsMap != null)
            {
                Validate(sharedTablesCommandsMap);
                AddUnchangedSharingEntries(sharedTablesCommandsMap, entries);
            }

            return(commands.Where(
                       c => c.EntityState != EntityState.Modified ||
                       c.ColumnModifications.Any(m => m.IsWrite)));
        }
Ejemplo n.º 41
0
 private static bool CanBeInsertedInSameStatement(ModificationCommand firstCommand, ModificationCommand secondCommand)
 => string.Equals(firstCommand.TableName, secondCommand.TableName, StringComparison.Ordinal) &&
 string.Equals(firstCommand.Schema, secondCommand.Schema, StringComparison.Ordinal) &&
 firstCommand.ColumnModifications.Where(o => o.IsWrite).Select(o => o.ColumnName).SequenceEqual(
     secondCommand.ColumnModifications.Where(o => o.IsWrite).Select(o => o.ColumnName)) &&
 firstCommand.ColumnModifications.Where(o => o.IsRead).Select(o => o.ColumnName).SequenceEqual(
     secondCommand.ColumnModifications.Where(o => o.IsRead).Select(o => o.ColumnName));
Ejemplo n.º 42
0
 protected override bool CanAddCommand(ModificationCommand modificationCommand)
 {
     return(ModificationCommands.Count < _maxBatchSize);
 }
Ejemplo n.º 43
0
 public override void AppendInsertOperation(StringBuilder commandStringBuilder, ModificationCommand command)
 {
     if (!string.IsNullOrEmpty(command.SchemaName))
     {
         commandStringBuilder.Append(command.SchemaName + ".");
     }
     commandStringBuilder.Append(command.TableName);
 }
 public override void AppendInsertOperation(StringBuilder commandStringBuilder, ModificationCommand command)
 {
     if (!string.IsNullOrEmpty(command.SchemaName))
     {
         commandStringBuilder.Append(command.SchemaName + ".");
     }
     commandStringBuilder.Append(command.TableName);
 }
Ejemplo n.º 45
0
        public virtual void AppendDeleteOperation(StringBuilder commandStringBuilder, ModificationCommand command)
        {
            Check.NotNull(command, nameof(command));

            var tableName           = command.TableName;
            var schemaName          = command.SchemaName;
            var conditionOperations = command.ColumnModifications.Where(o => o.IsCondition).ToArray();

            AppendDeleteCommand(commandStringBuilder, tableName, schemaName, conditionOperations);

            AppendSelectAffectedCountCommand(commandStringBuilder, tableName, schemaName);
        }
        public override ResultSetMapping AppendDeleteOperation(StringBuilder commandStringBuilder, ModificationCommand command, int commandPosition)
        {
            var sqlGenerationHelper = (IFbSqlGenerationHelper)SqlGenerationHelper;
            var name                = command.TableName;
            var operations          = command.ColumnModifications;
            var conditionOperations = operations.Where(o => o.IsCondition).ToList();
            var inputOperations     = GenerateParameters(conditionOperations);

            commandStringBuilder.Append("EXECUTE BLOCK (");
            commandStringBuilder.AppendJoin(inputOperations, (b, p) =>
            {
                b.Append(p.name);
                b.Append(" ");
                b.Append(p.type);
                b.Append(" = ?");
            }, ", ");
            commandStringBuilder.AppendLine(")");
            commandStringBuilder.AppendLine("RETURNS (ROWS_AFFECTED INT)");
            commandStringBuilder.AppendLine("AS");
            commandStringBuilder.AppendLine("BEGIN");
            var oldParameterNameMarker = sqlGenerationHelper.ParameterNameMarker;

            sqlGenerationHelper.ParameterNameMarker = ":";
            try
            {
                AppendDeleteCommandHeader(commandStringBuilder, name, null);
                AppendWhereClause(commandStringBuilder, conditionOperations);
            }
            finally
            {
                sqlGenerationHelper.ParameterNameMarker = oldParameterNameMarker;
            }
            commandStringBuilder.Append(SqlGenerationHelper.StatementTerminator).AppendLine();
            commandStringBuilder.AppendLine();
            commandStringBuilder.AppendLine("ROWS_AFFECTED = ROW_COUNT;");
            commandStringBuilder.AppendLine("SUSPEND;");
            commandStringBuilder.AppendLine("END");
            commandStringBuilder.Append(SqlGenerationHelper.StatementTerminator).AppendLine();
            return(ResultSetMapping.LastInResultSet);
        }
        private static int CountParameters(ModificationCommand modificationCommand)
        {
            var parameterCount = 0;
            foreach (var columnModification in modificationCommand.ColumnModifications)
            {
                if (columnModification.UseCurrentValueParameter)
                {
                    parameterCount++;
                }

                if (columnModification.UseOriginalValueParameter)
                {
                    parameterCount++;
                }
            }

            return parameterCount;
        }
        public override ResultSetMapping AppendInsertOperation(StringBuilder commandStringBuilder, ModificationCommand command, int commandPosition)
        {
            var result          = ResultSetMapping.NoResultSet;
            var name            = command.TableName;
            var operations      = command.ColumnModifications;
            var writeOperations = operations.Where(o => o.IsWrite).ToList();
            var readOperations  = operations.Where(o => o.IsRead).ToList();
            var anyRead         = readOperations.Any();

            AppendInsertCommandHeader(commandStringBuilder, name, null, writeOperations);
            AppendValuesHeader(commandStringBuilder, writeOperations);
            AppendValues(commandStringBuilder, writeOperations);
            if (anyRead)
            {
                commandStringBuilder.AppendLine();
                commandStringBuilder.Append("RETURNING ");
                commandStringBuilder.AppendJoin(readOperations, (b, e) =>
                {
                    b.Append(SqlGenerationHelper.DelimitIdentifier(e.ColumnName));
                }, ", ");
                result = ResultSetMapping.LastInResultSet;
            }
            commandStringBuilder.Append(SqlGenerationHelper.StatementTerminator).AppendLine();
            return(result);
        }
 protected override bool CanAddCommand(ModificationCommand modificationCommand)
 {
     return(ShouldAddCommand);
 }
        public override ResultSetMapping AppendUpdateOperation(StringBuilder commandStringBuilder, ModificationCommand command, int commandPosition)
        {
            var sqlGenerationHelper = (IFbSqlGenerationHelper)SqlGenerationHelper;
            var name                = command.TableName;
            var operations          = command.ColumnModifications;
            var writeOperations     = operations.Where(o => o.IsWrite).ToList();
            var readOperations      = operations.Where(o => o.IsRead).ToList();
            var conditionOperations = operations.Where(o => o.IsCondition).ToList();
            var inputOperations     = GenerateParameters(operations.Where(o => o.IsWrite || o.IsCondition)).ToList();
            var anyRead             = readOperations.Any();

            commandStringBuilder.Append("EXECUTE BLOCK (");
            commandStringBuilder.AppendJoin(inputOperations, (b, p) =>
            {
                b.Append(p.name);
                b.Append(" ");
                b.Append(p.type);
                b.Append(" = ?");
            }, ", ");
            commandStringBuilder.AppendLine(")");
            commandStringBuilder.Append("RETURNS (");
            if (anyRead)
            {
                commandStringBuilder.AppendJoin(readOperations, (b, e) =>
                {
                    var type = GetColumnType(e);
                    b.Append(SqlGenerationHelper.DelimitIdentifier(e.ColumnName));
                    b.Append(" ");
                    b.Append(type);
                }, ", ");
            }
            else
            {
                commandStringBuilder.Append("ROWS_AFFECTED INT");
            }
            commandStringBuilder.AppendLine(")");
            commandStringBuilder.AppendLine("AS");
            commandStringBuilder.AppendLine("BEGIN");
            var oldParameterNameMarker = sqlGenerationHelper.ParameterNameMarker;

            sqlGenerationHelper.ParameterNameMarker = ":";
            try
            {
                AppendUpdateCommandHeader(commandStringBuilder, name, null, writeOperations);
                AppendWhereClause(commandStringBuilder, conditionOperations);
            }
            finally
            {
                sqlGenerationHelper.ParameterNameMarker = oldParameterNameMarker;
            }
            if (anyRead)
            {
                commandStringBuilder.AppendLine();
                commandStringBuilder.Append("RETURNING ");

                commandStringBuilder.AppendJoin(readOperations, (b, e) =>
                {
                    b.Append(SqlGenerationHelper.DelimitIdentifier(e.ColumnName));
                }, ", ");
                commandStringBuilder.Append(" INTO ");
                commandStringBuilder.AppendJoin(readOperations, (b, e) =>
                {
                    b.Append(" :");
                    b.Append(SqlGenerationHelper.DelimitIdentifier(e.ColumnName));
                }, ", ");
            }
            commandStringBuilder.Append(SqlGenerationHelper.StatementTerminator).AppendLine();
            if (!anyRead)
            {
                commandStringBuilder.AppendLine("ROWS_AFFECTED = ROW_COUNT;");
                commandStringBuilder.AppendLine("SUSPEND;");
            }
            else
            {
                commandStringBuilder.AppendLine("IF (ROW_COUNT > 0) THEN");
                commandStringBuilder.AppendLine("SUSPEND;");
            }
            commandStringBuilder.AppendLine("END");
            commandStringBuilder.Append(SqlGenerationHelper.StatementTerminator).AppendLine();
            return(ResultSetMapping.LastInResultSet);
        }
Ejemplo n.º 51
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>
        protected virtual IEnumerable <ModificationCommand> CreateModificationCommands(
            [NotNull] IList <IUpdateEntry> entries,
            [NotNull] IUpdateAdapter updateAdapter,
            [NotNull] Func <string> generateParameterName)
        {
            var commands = new List <ModificationCommand>();

            if (_sharedTableEntryMapFactories == null)
            {
                _sharedTableEntryMapFactories = SharedTableEntryMap <ModificationCommand>
                                                .CreateSharedTableEntryMapFactories(updateAdapter.Model, updateAdapter);
            }

            Dictionary <(string Name, string Schema), SharedTableEntryMap <ModificationCommand> > sharedTablesCommandsMap =
                null;

            foreach (var entry in entries)
            {
                if (entry.SharedIdentityEntry != null &&
                    entry.EntityState == EntityState.Deleted)
                {
                    continue;
                }

                var entityType = entry.EntityType;
                var table      = entityType.GetTableName();
                var schema     = entityType.GetSchema();
                var tableKey   = (table, schema);

                ModificationCommand command;
                var isMainEntry = true;
                if (_sharedTableEntryMapFactories.TryGetValue(tableKey, out var commandIdentityMapFactory))
                {
                    if (sharedTablesCommandsMap == null)
                    {
                        sharedTablesCommandsMap =
                            new Dictionary <(string, string), SharedTableEntryMap <ModificationCommand> >();
                    }

                    if (!sharedTablesCommandsMap.TryGetValue(tableKey, out var sharedCommandsMap))
                    {
                        sharedCommandsMap = commandIdentityMapFactory(
                            (n, s, c) => new ModificationCommand(
                                n, s, generateParameterName, _sensitiveLoggingEnabled, c));
                        sharedTablesCommandsMap.Add(tableKey, sharedCommandsMap);
                    }

                    command     = sharedCommandsMap.GetOrAddValue(entry);
                    isMainEntry = sharedCommandsMap.IsMainEntityType(entry.EntityType.GetRootType());
                }
                else
                {
                    command = new ModificationCommand(
                        table, schema, generateParameterName, _sensitiveLoggingEnabled, comparer: null);
                }

                command.AddEntry(entry, isMainEntry);
                commands.Add(command);
            }

            if (sharedTablesCommandsMap != null)
            {
                AddUnchangedSharingEntries(sharedTablesCommandsMap.Values, entries);
            }

            return(commands.Where(
                       c => c.EntityState != EntityState.Modified ||
                       c.ColumnModifications.Any(m => m.IsWrite)));
        }
 /// <summary>
 /// </summary>
 /// <param name="modificationCommand"></param>
 /// <returns></returns>
 public override bool AddCommand(ModificationCommand modificationCommand)
 {
     _modificationCommands.Add(modificationCommand);
     return(true);
 }
 private bool CanBeInsertedInSameStatement(ModificationCommand firstCommand, ModificationCommand secondCommand)
     => string.Equals(firstCommand.TableName, secondCommand.TableName, StringComparison.Ordinal)
        && string.Equals(firstCommand.Schema, secondCommand.Schema, StringComparison.Ordinal)
        && firstCommand.ColumnModifications.Where(o => o.IsWrite).Select(o => o.ColumnName).SequenceEqual(
            secondCommand.ColumnModifications.Where(o => o.IsWrite).Select(o => o.ColumnName))
        && firstCommand.ColumnModifications.Where(o => o.IsRead).Select(o => o.ColumnName).SequenceEqual(
            secondCommand.ColumnModifications.Where(o => o.IsRead).Select(o => o.ColumnName));
Ejemplo n.º 54
0
        /// <summary>
        /// 更新缓存命令文本
        /// </summary>
        /// <param name="commandPosition"></param>
        protected override void UpdateCachedCommandText(int commandPosition)
        {
            try
            {
                if (Check.IsTraceEnabled(m_oracleLogger?.Logger))
                {
                    Trace <DbLoggerCategory.Update> .Write(m_oracleLogger, LogLevel.Trace, OracleTraceTag.Entry, OracleTraceClassName.OracleModificationCommandBatch, OracleTraceFuncName.UpdateCachedCommandText);
                }

                new StringBuilder();

                // The list of conceptual insert/update/delete
                // Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ModificationCommandss
                // in the batch.
                // 取得待处理的插入/更新/删除行的概念性命令,这意味着你应该对真实的执行命令自己进行组装
                ModificationCommand modificationCommand = ModificationCommands[commandPosition];

                // 对命令进行组装
                if (modificationCommand.EntityState == EntityState.Added)
                {
                    // Add命令
                    if (_batchInsertCommands.Count > 0 && !CanBeInserted(_batchInsertCommands.First().Key, modificationCommand))
                    {
                        CachedCommandText.Append(GetBatchInsertCommandText(commandPosition));
                        _batchInsertCommands.Clear();
                    }

                    if (ModificationCommands[commandPosition].ColumnModifications.Where((ColumnModification o) => o.IsRead).ToArray().Length != 0)
                    {
                        _batchInsertCommands.Add(modificationCommand, _cursorPosition);
                        _cursorPosition++;
                    }
                    else
                    {
                        _batchInsertCommands.Add(modificationCommand, 0);
                    }
                    LastCachedCommandIndex = commandPosition;
                }
                else if (modificationCommand.EntityState == EntityState.Deleted)
                {
                    // Delete命令
                    CachedCommandText.Append(GetBatchDeleteCommandText(commandPosition));
                    LastCachedCommandIndex = commandPosition;
                }
                else
                {
                    // Update命令
                    CachedCommandText.Append(GetBatchUpdateCommandText(commandPosition));
                    LastCachedCommandIndex = commandPosition;
                }
            }
            catch (Exception ex)
            {
                if (Check.IsErrorEnabled(m_oracleLogger?.Logger))
                {
                    Trace <DbLoggerCategory.Update> .Write(m_oracleLogger, LogLevel.Error, OracleTraceTag.Error, OracleTraceClassName.OracleModificationCommandBatch, OracleTraceFuncName.UpdateCachedCommandText, ex.ToString());
                }
                throw;
            }
            finally
            {
                if (Check.IsTraceEnabled(m_oracleLogger?.Logger))
                {
                    Trace <DbLoggerCategory.Update> .Write(m_oracleLogger, LogLevel.Trace, OracleTraceTag.Exit, OracleTraceClassName.OracleModificationCommandBatch, OracleTraceFuncName.UpdateCachedCommandText);
                }
            }
        }
Ejemplo n.º 55
0
        public void Compare_returns_0_only_for_commands_that_are_equal()
        {
            var mCC = new ModificationCommandComparer();

            var configuration = new DbContext(new DbContextOptions().UseInMemoryStore(persist: false)).Configuration;

            var entityType1 = new EntityType(typeof(object));
            var key1        = entityType1.GetOrAddProperty("Id", typeof(int), shadowProperty: true);

            entityType1.GetOrSetPrimaryKey(key1);
            var stateEntry1 = new MixedStateEntry(configuration, entityType1, new object());

            stateEntry1[key1]       = 0;
            stateEntry1.EntityState = EntityState.Added;
            var modificationCommandAdded = new ModificationCommand(new SchemaQualifiedName("A"), new ParameterNameGenerator());

            modificationCommandAdded.AddStateEntry(stateEntry1);

            var entityType2 = new EntityType(typeof(object));
            var key2        = entityType2.GetOrAddProperty("Id", typeof(int), shadowProperty: true);

            entityType2.GetOrSetPrimaryKey(key2);
            var stateEntry2 = new MixedStateEntry(configuration, entityType2, new object());

            stateEntry2[key2]       = 0;
            stateEntry2.EntityState = EntityState.Modified;
            var modificationCommandModified = new ModificationCommand(new SchemaQualifiedName("A"), new ParameterNameGenerator());

            modificationCommandModified.AddStateEntry(stateEntry2);

            var entityType3 = new EntityType(typeof(object));
            var key3        = entityType3.GetOrAddProperty("Id", typeof(int), shadowProperty: true);

            entityType3.GetOrSetPrimaryKey(key3);
            var stateEntry3 = new MixedStateEntry(configuration, entityType3, new object());

            stateEntry3[key3]       = 0;
            stateEntry3.EntityState = EntityState.Deleted;
            var modificationCommandDeleted = new ModificationCommand(new SchemaQualifiedName("A"), new ParameterNameGenerator());

            modificationCommandDeleted.AddStateEntry(stateEntry3);

            Assert.True(0 == mCC.Compare(modificationCommandAdded, modificationCommandAdded));
            Assert.True(0 == mCC.Compare(null, null));
            Assert.True(0 == mCC.Compare(
                            new ModificationCommand(new SchemaQualifiedName("A", "dbo"), new ParameterNameGenerator()),
                            new ModificationCommand(new SchemaQualifiedName("A", "dbo"), new ParameterNameGenerator())));

            Assert.True(0 > mCC.Compare(null, new ModificationCommand(new SchemaQualifiedName("A"), new ParameterNameGenerator())));
            Assert.True(0 < mCC.Compare(new ModificationCommand(new SchemaQualifiedName("A"), new ParameterNameGenerator()), null));

            Assert.True(0 > mCC.Compare(
                            new ModificationCommand(new SchemaQualifiedName("A"), new ParameterNameGenerator()),
                            new ModificationCommand(new SchemaQualifiedName("A", "dbo"), new ParameterNameGenerator())));
            Assert.True(0 < mCC.Compare(
                            new ModificationCommand(new SchemaQualifiedName("A", "dbo"), new ParameterNameGenerator()),
                            new ModificationCommand(new SchemaQualifiedName("A"), new ParameterNameGenerator())));

            Assert.True(0 > mCC.Compare(
                            new ModificationCommand(new SchemaQualifiedName("A", "dbo"), new ParameterNameGenerator()),
                            new ModificationCommand(new SchemaQualifiedName("A", "foo"), new ParameterNameGenerator())));
            Assert.True(0 < mCC.Compare(
                            new ModificationCommand(new SchemaQualifiedName("A", "foo"), new ParameterNameGenerator()),
                            new ModificationCommand(new SchemaQualifiedName("A", "dbo"), new ParameterNameGenerator())));

            Assert.True(0 > mCC.Compare(
                            new ModificationCommand(new SchemaQualifiedName("A"), new ParameterNameGenerator()),
                            new ModificationCommand(new SchemaQualifiedName("B"), new ParameterNameGenerator())));
            Assert.True(0 < mCC.Compare(
                            new ModificationCommand(new SchemaQualifiedName("B"), new ParameterNameGenerator()),
                            new ModificationCommand(new SchemaQualifiedName("A"), new ParameterNameGenerator())));

            Assert.True(0 > mCC.Compare(modificationCommandModified, modificationCommandAdded));
            Assert.True(0 < mCC.Compare(modificationCommandAdded, modificationCommandModified));

            Assert.True(0 > mCC.Compare(modificationCommandDeleted, modificationCommandAdded));
            Assert.True(0 < mCC.Compare(modificationCommandAdded, modificationCommandDeleted));

            Assert.True(0 > mCC.Compare(modificationCommandDeleted, modificationCommandModified));
            Assert.True(0 < mCC.Compare(modificationCommandModified, modificationCommandDeleted));
        }
 protected override bool CanAddCommand(ModificationCommand modificationCommand)
 {
     return ShouldAddCommand;
 }