使用DbCommand.ExecuteNonQueryAsync()> 0时不在数据库上执行查询;

问题描述 投票:0回答:2

我正在尝试在数据库上执行查询,因为无法在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;
        }
    }
c# mysql .net-core
2个回答
1
投票

也许连接没有打开?您呼叫connection.Open();,然后呼叫cmd.ExecuteNonQueryAsync()

也许您尝试使用OpenAsync。如果可用,取决于连接器。


0
投票

在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注入。

© www.soinside.com 2019 - 2024. All rights reserved.