Запрос не выполняется в базе данных при использовании DbCommand.ExecuteNonQueryAsyn c ()> 0; - PullRequest
0 голосов
/ 27 мая 2020

Я пытаюсь выполнить запрос в нашей базе данных, я создал его в текстовом виде, потому что я не могу сделать его достаточно эффективно в Entity Framework Core.

Это код, который я использую, но похоже он не выполняется в базе данных (я не вижу записи об этой транзакции в базе данных), но я также не получаю ошибок. Что я делаю не так?

    public async Task<CleanupObservationsResponse> Handle(CleanupObservationsCommand request, CancellationToken cancellationToken)
    {
        var removalDate = DateTime.Now.AddMonths(-3);
        _logger.LogInformation($"Started cleaning up observations for all observations before {removalDate.Date.ToString("yyyy-MM-dd")}");
        await _observationRepository.CleanupObservations(removalDate);
    }

    public Task<bool> CleanupObservations(DateTime removalDate)
    {
        var sql = $"START TRANSACTION;" +
        $"SET @RemovalDate := \"{removalDate.ToString("yyyy-MM-dd")}\";" +
        $"# MySql Variables can only store 1 row and thus the results of this query cannot be saved in a variable." +
        $"# SET @observationsToDelete := (SELECT Identification FROM cpp.Observation WHERE StartedUtc < @RemovalDate);" +
        $"DELETE FROM PropertyValues WHERE ObservationIdentification IN(SELECT Identification FROM Observation WHERE StartedUtc < @RemovalDate);" +
        $"DELETE FROM HoldReasonObservation WHERE ObservationIdentification IN(SELECT Identification FROM Observation WHERE StartedUtc < @RemovalDate);" +
        $"DELETE FROM ObservationDeviation WHERE ObservationIdentification IN(SELECT Identification FROM Observation WHERE StartedUtc < @RemovalDate);" +
        $"DELETE FROM ObservationQRTokens WHERE ObservationIdentification IN(SELECT Identification FROM Observation WHERE StartedUtc < @RemovalDate);" +
        $"DELETE FROM ObservationTarra WHERE ObservationIdentification IN(SELECT Identification FROM Observation WHERE StartedUtc < @RemovalDate);" +
        $"DELETE FROM Alibi WHERE ObservationIdentification IN(SELECT Identification FROM Observation WHERE StartedUtc < @RemovalDate);" +
        $"DELETE FROM PackageTrackingIdentifications WHERE ObservationIdentification IN(SELECT Identification FROM Observation WHERE StartedUtc < @RemovalDate);" +
        $"DELETE FROM QuestionAnswer WHERE ObservationIdentification IN(SELECT Identification FROM Observation WHERE StartedUtc < @RemovalDate);" +
        $"DELETE FROM Observation WHERE StartedUtc < @RemovalDate;" +
        $"COMMIT;";

        return this.ExecuteSQL(sql);
    }

    private async Task<bool> ExecuteSQL(string sql)
    {
        var connection = Context.Database.GetDbConnection();
        using (var cmd = connection.CreateCommand())
        {
            cmd.CommandText = sql;
            cmd.CommandType = CommandType.Text;

            if (connection.State != ConnectionState.Open)
            {
                connection.Open();
            }

            return await cmd.ExecuteNonQueryAsync() > 0;
        }
    }

Ответы [ 2 ]

1 голос
/ 27 мая 2020

В MySQL комментарий, начинающийся с #, продолжается до конца строки. (См. https://dev.mysql.com/doc/refman/8.0/en/comments.html.)

Ваш необработанный код SQL не содержит новых строк, поэтому комментарий, начинающийся с # MySql Variables can only store, включает весь оставшийся текст, и ничего не выполняется .

Я бы переписал эту строку, используя дословную C# строку (не интерполированную):

var sql = @"START TRANSACTION;
        SET @RemovalDate := ""{removalDate.ToString("yyyy-MM-dd")}"";
        # MySql Variables can only store 1 row and thus the results of this query cannot be saved in a variable.
        # SET @observationsToDelete := (SELECT Identification FROM cpp.Observation WHERE StartedUtc < @RemovalDate);
        DELETE FROM PropertyValues WHERE ObservationIdentification IN(SELECT Identification FROM Observation WHERE StartedUtc < @RemovalDate);
        DELETE FROM HoldReasonObservation WHERE ObservationIdentification IN(SELECT Identification FROM Observation WHERE StartedUtc < @RemovalDate);
        DELETE FROM ObservationDeviation WHERE ObservationIdentification IN(SELECT Identification FROM Observation WHERE StartedUtc < @RemovalDate);
        DELETE FROM ObservationQRTokens WHERE ObservationIdentification IN(SELECT Identification FROM Observation WHERE StartedUtc < @RemovalDate);
        DELETE FROM ObservationTarra WHERE ObservationIdentification IN(SELECT Identification FROM Observation WHERE StartedUtc < @RemovalDate);
        DELETE FROM Alibi WHERE ObservationIdentification IN(SELECT Identification FROM Observation WHERE StartedUtc < @RemovalDate);
        DELETE FROM PackageTrackingIdentifications WHERE ObservationIdentification IN(SELECT Identification FROM Observation WHERE StartedUtc < @RemovalDate);
        DELETE FROM QuestionAnswer WHERE ObservationIdentification IN(SELECT Identification FROM Observation WHERE StartedUtc < @RemovalDate);
        DELETE FROM Observation WHERE StartedUtc < @RemovalDate;
        COMMIT;";

Также было бы лучше удалить вашу переменную SQL (SET @RemovalDate := ""{removalDate.ToString("yyyy-MM-dd")}"";) и используйте реальные параметры команды:

cmd.Parameters.AddWithValue("@RemovalDate", removalDate);

Это позволит коннектору MySQL правильно отформатировать дату для вас и поможет избежать внедрения SQL.

1 голос
/ 27 мая 2020

Может быть, соединение не открыто? Вы вызываете connection.Open();, а затем cmd.ExecuteNonQueryAsync()

Может быть, вы вместо этого попробуете OpenAsyn c. Если он доступен, в зависимости от вашего разъема.

...