diff --git a/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.PagingQueryingEnumerable.cs b/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.PagingQueryingEnumerable.cs index 8d19f31596b..272a81c77ca 100644 --- a/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.PagingQueryingEnumerable.cs +++ b/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.PagingQueryingEnumerable.cs @@ -148,85 +148,78 @@ private async Task MoveNextCore() try { - _concurrencyDetector?.EnterCriticalSection(); + using var _ = _concurrencyDetector?.EnterCriticalSection(); - try + if (_hasExecuted) { - if (_hasExecuted) - { - return false; - } + return false; + } - _hasExecuted = true; + _hasExecuted = true; - var maxItemCount = (int)_cosmosQueryContext.ParameterValues[_queryingEnumerable._maxItemCountParameterName]; - var continuationToken = - (string)_cosmosQueryContext.ParameterValues[_queryingEnumerable._continuationTokenParameterName]; - var responseContinuationTokenLimitInKb = (int?) - _cosmosQueryContext.ParameterValues[_queryingEnumerable._responseContinuationTokenLimitInKbParameterName]; + var maxItemCount = (int)_cosmosQueryContext.ParameterValues[_queryingEnumerable._maxItemCountParameterName]; + var continuationToken = + (string)_cosmosQueryContext.ParameterValues[_queryingEnumerable._continuationTokenParameterName]; + var responseContinuationTokenLimitInKb = (int?) + _cosmosQueryContext.ParameterValues[_queryingEnumerable._responseContinuationTokenLimitInKbParameterName]; - var sqlQuery = _queryingEnumerable.GenerateQuery(); + var sqlQuery = _queryingEnumerable.GenerateQuery(); - EntityFrameworkMetricsData.ReportQueryExecuting(); + EntityFrameworkMetricsData.ReportQueryExecuting(); - var queryRequestOptions = new QueryRequestOptions - { - ResponseContinuationTokenLimitInKb = responseContinuationTokenLimitInKb - }; + var queryRequestOptions = new QueryRequestOptions + { + ResponseContinuationTokenLimitInKb = responseContinuationTokenLimitInKb + }; - if (_cosmosPartitionKeyValue != PartitionKey.None) - { - queryRequestOptions.PartitionKey = _cosmosPartitionKeyValue; - } + if (_cosmosPartitionKeyValue != PartitionKey.None) + { + queryRequestOptions.PartitionKey = _cosmosPartitionKeyValue; + } + + var cosmosClient = _cosmosQueryContext.CosmosClient; + _commandLogger.ExecutingSqlQuery(_cosmosContainer, _cosmosPartitionKeyValue, sqlQuery); + _cosmosQueryContext.InitializeStateManager(_standAloneStateManager); - var cosmosClient = _cosmosQueryContext.CosmosClient; - _commandLogger.ExecutingSqlQuery(_cosmosContainer, _cosmosPartitionKeyValue, sqlQuery); - _cosmosQueryContext.InitializeStateManager(_standAloneStateManager); + var results = new List(maxItemCount); - var results = new List(maxItemCount); + while (maxItemCount > 0) + { + queryRequestOptions.MaxItemCount = maxItemCount; + using var feedIterator = cosmosClient.CreateQuery( + _cosmosContainer, sqlQuery, continuationToken, queryRequestOptions); + + using var responseMessage = await feedIterator.ReadNextAsync(_cancellationToken).ConfigureAwait(false); + + _commandLogger.ExecutedReadNext( + responseMessage.Diagnostics.GetClientElapsedTime(), + responseMessage.Headers.RequestCharge, + responseMessage.Headers.ActivityId, + _cosmosContainer, + _cosmosPartitionKeyValue, + sqlQuery); - while (maxItemCount > 0) + responseMessage.EnsureSuccessStatusCode(); + + var responseMessageEnumerable = cosmosClient.GetResponseMessageEnumerable(responseMessage); + foreach (var resultObject in responseMessageEnumerable) { - queryRequestOptions.MaxItemCount = maxItemCount; - using var feedIterator = cosmosClient.CreateQuery( - _cosmosContainer, sqlQuery, continuationToken, queryRequestOptions); - - using var responseMessage = await feedIterator.ReadNextAsync(_cancellationToken).ConfigureAwait(false); - - _commandLogger.ExecutedReadNext( - responseMessage.Diagnostics.GetClientElapsedTime(), - responseMessage.Headers.RequestCharge, - responseMessage.Headers.ActivityId, - _cosmosContainer, - _cosmosPartitionKeyValue, - sqlQuery); - - responseMessage.EnsureSuccessStatusCode(); - - var responseMessageEnumerable = cosmosClient.GetResponseMessageEnumerable(responseMessage); - foreach (var resultObject in responseMessageEnumerable) - { - results.Add(_shaper(_cosmosQueryContext, resultObject)); - maxItemCount--; - } - - continuationToken = responseMessage.ContinuationToken; - - if (responseMessage.ContinuationToken is null) - { - break; - } + results.Add(_shaper(_cosmosQueryContext, resultObject)); + maxItemCount--; } - Current = new CosmosPage(results, continuationToken); + continuationToken = responseMessage.ContinuationToken; - _hasExecuted = true; - return true; - } - finally - { - _concurrencyDetector?.ExitCriticalSection(); + if (responseMessage.ContinuationToken is null) + { + break; + } } + + Current = new CosmosPage(results, continuationToken); + + _hasExecuted = true; + return true; } catch (Exception exception) { diff --git a/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.QueryingEnumerable.cs b/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.QueryingEnumerable.cs index cf0876f47fc..705ef00ea79 100644 --- a/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.QueryingEnumerable.cs +++ b/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.QueryingEnumerable.cs @@ -147,35 +147,28 @@ public bool MoveNext() { try { - _concurrencyDetector?.EnterCriticalSection(); + using var _ = _concurrencyDetector?.EnterCriticalSection(); - try + if (_enumerator == null) { - if (_enumerator == null) - { - var sqlQuery = _queryingEnumerable.GenerateQuery(); + var sqlQuery = _queryingEnumerable.GenerateQuery(); - EntityFrameworkMetricsData.ReportQueryExecuting(); + EntityFrameworkMetricsData.ReportQueryExecuting(); - _enumerator = _cosmosQueryContext.CosmosClient - .ExecuteSqlQuery(_cosmosContainer, _cosmosPartitionKeyValue, sqlQuery) - .GetEnumerator(); - _cosmosQueryContext.InitializeStateManager(_standAloneStateManager); - } + _enumerator = _cosmosQueryContext.CosmosClient + .ExecuteSqlQuery(_cosmosContainer, _cosmosPartitionKeyValue, sqlQuery) + .GetEnumerator(); + _cosmosQueryContext.InitializeStateManager(_standAloneStateManager); + } - var hasNext = _enumerator.MoveNext(); + var hasNext = _enumerator.MoveNext(); - Current - = hasNext - ? _shaper(_cosmosQueryContext, _enumerator.Current) - : default; + Current + = hasNext + ? _shaper(_cosmosQueryContext, _enumerator.Current) + : default; - return hasNext; - } - finally - { - _concurrencyDetector?.ExitCriticalSection(); - } + return hasNext; } catch (Exception exception) { @@ -242,35 +235,28 @@ public async ValueTask MoveNextAsync() { try { - _concurrencyDetector?.EnterCriticalSection(); + using var _ = _concurrencyDetector?.EnterCriticalSection(); - try + if (_enumerator == null) { - if (_enumerator == null) - { - var sqlQuery = _queryingEnumerable.GenerateQuery(); + var sqlQuery = _queryingEnumerable.GenerateQuery(); - EntityFrameworkMetricsData.ReportQueryExecuting(); + EntityFrameworkMetricsData.ReportQueryExecuting(); - _enumerator = _cosmosQueryContext.CosmosClient - .ExecuteSqlQueryAsync(_cosmosContainer, _cosmosPartitionKeyValue, sqlQuery) - .GetAsyncEnumerator(_cancellationToken); - _cosmosQueryContext.InitializeStateManager(_standAloneStateManager); - } + _enumerator = _cosmosQueryContext.CosmosClient + .ExecuteSqlQueryAsync(_cosmosContainer, _cosmosPartitionKeyValue, sqlQuery) + .GetAsyncEnumerator(_cancellationToken); + _cosmosQueryContext.InitializeStateManager(_standAloneStateManager); + } - var hasNext = await _enumerator.MoveNextAsync().ConfigureAwait(false); + var hasNext = await _enumerator.MoveNextAsync().ConfigureAwait(false); - Current - = hasNext - ? _shaper(_cosmosQueryContext, _enumerator.Current) - : default; + Current + = hasNext + ? _shaper(_cosmosQueryContext, _enumerator.Current) + : default; - return hasNext; - } - finally - { - _concurrencyDetector?.ExitCriticalSection(); - } + return hasNext; } catch (Exception exception) { diff --git a/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.ReadItemQueryingEnumerable.cs b/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.ReadItemQueryingEnumerable.cs index ffe797e53c8..de9dff32bdf 100644 --- a/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.ReadItemQueryingEnumerable.cs +++ b/src/EFCore.Cosmos/Query/Internal/CosmosShapedQueryCompilingExpressionVisitor.ReadItemQueryingEnumerable.cs @@ -177,38 +177,31 @@ public bool MoveNext() { try { - _concurrencyDetector?.EnterCriticalSection(); + using var _ = _concurrencyDetector?.EnterCriticalSection(); - try + if (_hasExecuted) { - if (!_hasExecuted) - { - if (!_readItemEnumerable.TryGetResourceId(out var resourceId)) - { - throw new InvalidOperationException(CosmosStrings.ResourceIdMissing); - } + return false; + } - if (!_readItemEnumerable.TryGetPartitionKey(out var partitionKeyValue)) - { - throw new InvalidOperationException(CosmosStrings.PartitionKeyMissing); - } + if (!_readItemEnumerable.TryGetResourceId(out var resourceId)) + { + throw new InvalidOperationException(CosmosStrings.ResourceIdMissing); + } - EntityFrameworkMetricsData.ReportQueryExecuting(); + if (!_readItemEnumerable.TryGetPartitionKey(out var partitionKeyValue)) + { + throw new InvalidOperationException(CosmosStrings.PartitionKeyMissing); + } - _item = _cosmosQueryContext.CosmosClient.ExecuteReadItem( - _cosmosContainer, - partitionKeyValue, - resourceId); + EntityFrameworkMetricsData.ReportQueryExecuting(); - return ShapeResult(); - } + _item = _cosmosQueryContext.CosmosClient.ExecuteReadItem( + _cosmosContainer, + partitionKeyValue, + resourceId); - return false; - } - finally - { - _concurrencyDetector?.ExitCriticalSection(); - } + return ShapeResult(); } catch (Exception exception) { @@ -229,40 +222,33 @@ public async ValueTask MoveNextAsync() { try { - _concurrencyDetector?.EnterCriticalSection(); + using var _ = _concurrencyDetector?.EnterCriticalSection(); - try + if (_hasExecuted) { - if (!_hasExecuted) - { - if (!_readItemEnumerable.TryGetResourceId(out var resourceId)) - { - throw new InvalidOperationException(CosmosStrings.ResourceIdMissing); - } - - if (!_readItemEnumerable.TryGetPartitionKey(out var partitionKeyValue)) - { - throw new InvalidOperationException(CosmosStrings.PartitionKeyMissing); - } - - EntityFrameworkMetricsData.ReportQueryExecuting(); - - _item = await _cosmosQueryContext.CosmosClient.ExecuteReadItemAsync( - _cosmosContainer, - partitionKeyValue, - resourceId, - _cancellationToken) - .ConfigureAwait(false); - - return ShapeResult(); - } - return false; } - finally + + if (!_readItemEnumerable.TryGetResourceId(out var resourceId)) { - _concurrencyDetector?.ExitCriticalSection(); + throw new InvalidOperationException(CosmosStrings.ResourceIdMissing); } + + if (!_readItemEnumerable.TryGetPartitionKey(out var partitionKeyValue)) + { + throw new InvalidOperationException(CosmosStrings.PartitionKeyMissing); + } + + EntityFrameworkMetricsData.ReportQueryExecuting(); + + _item = await _cosmosQueryContext.CosmosClient.ExecuteReadItemAsync( + _cosmosContainer, + partitionKeyValue, + resourceId, + _cancellationToken) + .ConfigureAwait(false); + + return ShapeResult(); } catch (Exception exception) { diff --git a/src/EFCore.InMemory/Query/Internal/InMemoryShapedQueryCompilingExpressionVisitor.QueryingEnumerable.cs b/src/EFCore.InMemory/Query/Internal/InMemoryShapedQueryCompilingExpressionVisitor.QueryingEnumerable.cs index b14c222994b..4128f871667 100644 --- a/src/EFCore.InMemory/Query/Internal/InMemoryShapedQueryCompilingExpressionVisitor.QueryingEnumerable.cs +++ b/src/EFCore.InMemory/Query/Internal/InMemoryShapedQueryCompilingExpressionVisitor.QueryingEnumerable.cs @@ -93,16 +93,9 @@ public bool MoveNext() { try { - _concurrencyDetector?.EnterCriticalSection(); + using var _ = _concurrencyDetector?.EnterCriticalSection(); - try - { - return MoveNextHelper(); - } - finally - { - _concurrencyDetector?.ExitCriticalSection(); - } + return MoveNextHelper(); } catch (Exception exception) { @@ -123,18 +116,11 @@ public ValueTask MoveNextAsync() { try { - _concurrencyDetector?.EnterCriticalSection(); + using var _ = _concurrencyDetector?.EnterCriticalSection(); - try - { - _cancellationToken.ThrowIfCancellationRequested(); + _cancellationToken.ThrowIfCancellationRequested(); - return ValueTask.FromResult(MoveNextHelper()); - } - finally - { - _concurrencyDetector?.ExitCriticalSection(); - } + return ValueTask.FromResult(MoveNextHelper()); } catch (Exception exception) { diff --git a/src/EFCore.Relational/Extensions/RelationalDatabaseFacadeExtensions.cs b/src/EFCore.Relational/Extensions/RelationalDatabaseFacadeExtensions.cs index 4e854768ce8..c2cd5273beb 100644 --- a/src/EFCore.Relational/Extensions/RelationalDatabaseFacadeExtensions.cs +++ b/src/EFCore.Relational/Extensions/RelationalDatabaseFacadeExtensions.cs @@ -292,27 +292,20 @@ public static int ExecuteSqlRaw( : null; var logger = facadeDependencies.CommandLogger; - concurrencyDetector?.EnterCriticalSection(); - - try - { - var rawSqlCommand = facadeDependencies.RawSqlCommandBuilder - .Build(sql, parameters, databaseFacade.GetService()); - - return rawSqlCommand - .RelationalCommand - .ExecuteNonQuery( - new RelationalCommandParameterObject( - facadeDependencies.RelationalConnection, - rawSqlCommand.ParameterValues, - null, - ((IDatabaseFacadeDependenciesAccessor)databaseFacade).Context, - logger, CommandSource.ExecuteSqlRaw)); - } - finally - { - concurrencyDetector?.ExitCriticalSection(); - } + using var _ = concurrencyDetector?.EnterCriticalSection(); + + var rawSqlCommand = facadeDependencies.RawSqlCommandBuilder + .Build(sql, parameters, databaseFacade.GetService()); + + return rawSqlCommand + .RelationalCommand + .ExecuteNonQuery( + new RelationalCommandParameterObject( + facadeDependencies.RelationalConnection, + rawSqlCommand.ParameterValues, + null, + ((IDatabaseFacadeDependenciesAccessor)databaseFacade).Context, + logger, CommandSource.ExecuteSqlRaw)); } /// @@ -608,29 +601,22 @@ public static async Task ExecuteSqlRawAsync( : null; var logger = facadeDependencies.CommandLogger; - concurrencyDetector?.EnterCriticalSection(); - - try - { - var rawSqlCommand = facadeDependencies.RawSqlCommandBuilder - .Build(sql, parameters, databaseFacade.GetService()); - - return await rawSqlCommand - .RelationalCommand - .ExecuteNonQueryAsync( - new RelationalCommandParameterObject( - facadeDependencies.RelationalConnection, - rawSqlCommand.ParameterValues, - null, - ((IDatabaseFacadeDependenciesAccessor)databaseFacade).Context, - logger, CommandSource.ExecuteSqlRaw), - cancellationToken) - .ConfigureAwait(false); - } - finally - { - concurrencyDetector?.ExitCriticalSection(); - } + using var _ = concurrencyDetector?.EnterCriticalSection(); + + var rawSqlCommand = facadeDependencies.RawSqlCommandBuilder + .Build(sql, parameters, databaseFacade.GetService()); + + return await rawSqlCommand + .RelationalCommand + .ExecuteNonQueryAsync( + new RelationalCommandParameterObject( + facadeDependencies.RelationalConnection, + rawSqlCommand.ParameterValues, + null, + ((IDatabaseFacadeDependenciesAccessor)databaseFacade).Context, + logger, CommandSource.ExecuteSqlRaw), + cancellationToken) + .ConfigureAwait(false); } /// diff --git a/src/EFCore.Relational/Query/Internal/FromSqlQueryingEnumerable.cs b/src/EFCore.Relational/Query/Internal/FromSqlQueryingEnumerable.cs index c54a0d5a583..3bdd96e16b3 100644 --- a/src/EFCore.Relational/Query/Internal/FromSqlQueryingEnumerable.cs +++ b/src/EFCore.Relational/Query/Internal/FromSqlQueryingEnumerable.cs @@ -229,27 +229,20 @@ public bool MoveNext() { try { - _concurrencyDetector?.EnterCriticalSection(); + using var _ = _concurrencyDetector?.EnterCriticalSection(); - try + if (_dataReader == null) { - if (_dataReader == null) - { - _relationalQueryContext.ExecutionStrategy.Execute(this, (_, enumerator) => InitializeReader(enumerator), null); - } + _relationalQueryContext.ExecutionStrategy.Execute(this, (_, enumerator) => InitializeReader(enumerator), null); + } - var hasNext = _dataReader!.Read(); + var hasNext = _dataReader!.Read(); - Current = hasNext - ? _shaper(_relationalQueryContext, _dataReader.DbDataReader, _indexMap!) - : default!; + Current = hasNext + ? _shaper(_relationalQueryContext, _dataReader.DbDataReader, _indexMap!) + : default!; - return hasNext; - } - finally - { - _concurrencyDetector?.ExitCriticalSection(); - } + return hasNext; } catch (Exception exception) { @@ -346,32 +339,25 @@ public async ValueTask MoveNextAsync() { try { - _concurrencyDetector?.EnterCriticalSection(); + using var _ = _concurrencyDetector?.EnterCriticalSection(); - try + if (_dataReader == null) { - if (_dataReader == null) - { - await _relationalQueryContext.ExecutionStrategy.ExecuteAsync( - this, - (_, enumerator, cancellationToken) => InitializeReaderAsync(enumerator, cancellationToken), - null, - _relationalQueryContext.CancellationToken) - .ConfigureAwait(false); - } - - var hasNext = await _dataReader!.ReadAsync(_relationalQueryContext.CancellationToken).ConfigureAwait(false); - - Current = hasNext - ? _shaper(_relationalQueryContext, _dataReader.DbDataReader, _indexMap!) - : default!; - - return hasNext; - } - finally - { - _concurrencyDetector?.ExitCriticalSection(); + await _relationalQueryContext.ExecutionStrategy.ExecuteAsync( + this, + (_, enumerator, cancellationToken) => InitializeReaderAsync(enumerator, cancellationToken), + null, + _relationalQueryContext.CancellationToken) + .ConfigureAwait(false); } + + var hasNext = await _dataReader!.ReadAsync(_relationalQueryContext.CancellationToken).ConfigureAwait(false); + + Current = hasNext + ? _shaper(_relationalQueryContext, _dataReader.DbDataReader, _indexMap!) + : default!; + + return hasNext; } catch (Exception exception) { diff --git a/src/EFCore.Relational/Query/Internal/GroupBySingleQueryingEnumerable.cs b/src/EFCore.Relational/Query/Internal/GroupBySingleQueryingEnumerable.cs index 7df321fe48e..7caf9498228 100644 --- a/src/EFCore.Relational/Query/Internal/GroupBySingleQueryingEnumerable.cs +++ b/src/EFCore.Relational/Query/Internal/GroupBySingleQueryingEnumerable.cs @@ -243,83 +243,76 @@ public bool MoveNext() { try { - _concurrencyDetector?.EnterCriticalSection(); + using var _ = _concurrencyDetector?.EnterCriticalSection(); - try + if (_dataReader == null) { - if (_dataReader == null) - { - _relationalQueryContext.ExecutionStrategy.Execute( - this, static (_, enumerator) => InitializeReader(enumerator), null); - } + _relationalQueryContext.ExecutionStrategy.Execute( + this, static (_, enumerator) => InitializeReader(enumerator), null); + } - var hasNext = _resultCoordinator!.HasNext ?? _dataReader!.Read(); + var hasNext = _resultCoordinator!.HasNext ?? _dataReader!.Read(); - if (hasNext) + if (hasNext) + { + var key = _keySelector(_relationalQueryContext, _dbDataReader!); + var keyIdentifier = _keyIdentifier(_relationalQueryContext, _dbDataReader!); + var group = new InternalGrouping(key); + do { - var key = _keySelector(_relationalQueryContext, _dbDataReader!); - var keyIdentifier = _keyIdentifier(_relationalQueryContext, _dbDataReader!); - var group = new InternalGrouping(key); - do + _resultCoordinator.ResultReady = true; + _resultCoordinator.HasNext = null; + var element = _elementSelector( + _relationalQueryContext, _dbDataReader!, _resultCoordinator.ResultContext, _resultCoordinator); + if (_resultCoordinator.ResultReady) { - _resultCoordinator.ResultReady = true; - _resultCoordinator.HasNext = null; - var element = _elementSelector( - _relationalQueryContext, _dbDataReader!, _resultCoordinator.ResultContext, _resultCoordinator); - if (_resultCoordinator.ResultReady) + _resultCoordinator.ResultContext.Values = null; + group.Add(element); + } + + if (_resultCoordinator!.HasNext ?? _dbDataReader!.Read()) + { + if (!_resultCoordinator.ResultReady) { - _resultCoordinator.ResultContext.Values = null; - group.Add(element); + // If result isn't ready, we are still materializing element. + continue; } - if (_resultCoordinator!.HasNext ?? _dbDataReader!.Read()) + // Check if grouping key changed + if (!CompareIdentifiers( + _keyIdentifierValueComparers, keyIdentifier, + _keyIdentifier(_relationalQueryContext, _dbDataReader!))) { - if (!_resultCoordinator.ResultReady) - { - // If result isn't ready, we are still materializing element. - continue; - } - - // Check if grouping key changed - if (!CompareIdentifiers( - _keyIdentifierValueComparers, keyIdentifier, - _keyIdentifier(_relationalQueryContext, _dbDataReader!))) - { - _resultCoordinator.HasNext = true; - Current = group; - break; - } + _resultCoordinator.HasNext = true; + Current = group; + break; } - else + } + else + { + // End of enumeration so materialize final element if any and add it. + if (!_resultCoordinator.ResultReady) { - // End of enumeration so materialize final element if any and add it. - if (!_resultCoordinator.ResultReady) - { - _resultCoordinator.HasNext = false; - _resultCoordinator.ResultReady = true; - element = _elementSelector( - _relationalQueryContext, _dbDataReader!, _resultCoordinator.ResultContext, _resultCoordinator); - - group.Add(element); - } + _resultCoordinator.HasNext = false; + _resultCoordinator.ResultReady = true; + element = _elementSelector( + _relationalQueryContext, _dbDataReader!, _resultCoordinator.ResultContext, _resultCoordinator); - Current = group; - break; + group.Add(element); } + + Current = group; + break; } - while (true); } - else - { - Current = default!; - } - - return hasNext; + while (true); } - finally + else { - _concurrencyDetector?.ExitCriticalSection(); + Current = default!; } + + return hasNext; } catch (Exception exception) { @@ -426,87 +419,80 @@ public async ValueTask MoveNextAsync() { try { - _concurrencyDetector?.EnterCriticalSection(); + using var _ = _concurrencyDetector?.EnterCriticalSection(); - try + if (_dataReader == null) { - if (_dataReader == null) - { - await _relationalQueryContext.ExecutionStrategy.ExecuteAsync( - this, - static (_, enumerator, cancellationToken) => InitializeReaderAsync(enumerator, cancellationToken), - null, - _cancellationToken) - .ConfigureAwait(false); - } + await _relationalQueryContext.ExecutionStrategy.ExecuteAsync( + this, + static (_, enumerator, cancellationToken) => InitializeReaderAsync(enumerator, cancellationToken), + null, + _cancellationToken) + .ConfigureAwait(false); + } - var hasNext = _resultCoordinator!.HasNext ?? await _dataReader!.ReadAsync(_cancellationToken).ConfigureAwait(false); + var hasNext = _resultCoordinator!.HasNext ?? await _dataReader!.ReadAsync(_cancellationToken).ConfigureAwait(false); - if (hasNext) + if (hasNext) + { + var key = _keySelector(_relationalQueryContext, _dbDataReader!); + var keyIdentifier = _keyIdentifier(_relationalQueryContext, _dbDataReader!); + var group = new InternalGrouping(key); + do { - var key = _keySelector(_relationalQueryContext, _dbDataReader!); - var keyIdentifier = _keyIdentifier(_relationalQueryContext, _dbDataReader!); - var group = new InternalGrouping(key); - do + _resultCoordinator.ResultReady = true; + _resultCoordinator.HasNext = null; + var element = _elementSelector( + _relationalQueryContext, _dbDataReader!, _resultCoordinator.ResultContext, _resultCoordinator); + if (_resultCoordinator.ResultReady) { - _resultCoordinator.ResultReady = true; - _resultCoordinator.HasNext = null; - var element = _elementSelector( - _relationalQueryContext, _dbDataReader!, _resultCoordinator.ResultContext, _resultCoordinator); - if (_resultCoordinator.ResultReady) + _resultCoordinator.ResultContext.Values = null; + group.Add(element); + } + + if (_resultCoordinator!.HasNext ?? await _dataReader!.ReadAsync(_cancellationToken).ConfigureAwait(false)) + { + if (!_resultCoordinator.ResultReady) { - _resultCoordinator.ResultContext.Values = null; - group.Add(element); + // If result isn't ready, we are still materializing element. + continue; } - if (_resultCoordinator!.HasNext ?? await _dataReader!.ReadAsync(_cancellationToken).ConfigureAwait(false)) + // Check if grouping key changed + if (!CompareIdentifiers( + _keyIdentifierValueComparers, keyIdentifier, + _keyIdentifier(_relationalQueryContext, _dbDataReader!))) { - if (!_resultCoordinator.ResultReady) - { - // If result isn't ready, we are still materializing element. - continue; - } - - // Check if grouping key changed - if (!CompareIdentifiers( - _keyIdentifierValueComparers, keyIdentifier, - _keyIdentifier(_relationalQueryContext, _dbDataReader!))) - { - _resultCoordinator.HasNext = true; - Current = group; - break; - } + _resultCoordinator.HasNext = true; + Current = group; + break; } - else + } + else + { + // End of enumeration so materialize final element if any and add it. + if (!_resultCoordinator.ResultReady) { - // End of enumeration so materialize final element if any and add it. - if (!_resultCoordinator.ResultReady) - { - _resultCoordinator.HasNext = false; - _resultCoordinator.ResultReady = true; - element = _elementSelector( - _relationalQueryContext, _dbDataReader!, _resultCoordinator.ResultContext, _resultCoordinator); - - group.Add(element); - } + _resultCoordinator.HasNext = false; + _resultCoordinator.ResultReady = true; + element = _elementSelector( + _relationalQueryContext, _dbDataReader!, _resultCoordinator.ResultContext, _resultCoordinator); - Current = group; - break; + group.Add(element); } + + Current = group; + break; } - while (true); } - else - { - Current = default!; - } - - return hasNext; + while (true); } - finally + else { - _concurrencyDetector?.ExitCriticalSection(); + Current = default!; } + + return hasNext; } catch (Exception exception) { diff --git a/src/EFCore.Relational/Query/Internal/GroupBySplitQueryingEnumerable.cs b/src/EFCore.Relational/Query/Internal/GroupBySplitQueryingEnumerable.cs index 6f3c0ab09e4..982b59dcdb6 100644 --- a/src/EFCore.Relational/Query/Internal/GroupBySplitQueryingEnumerable.cs +++ b/src/EFCore.Relational/Query/Internal/GroupBySplitQueryingEnumerable.cs @@ -255,71 +255,64 @@ public bool MoveNext() { try { - _concurrencyDetector?.EnterCriticalSection(); + using var _ = _concurrencyDetector?.EnterCriticalSection(); - try + if (_dataReader == null) { - if (_dataReader == null) - { - _relationalQueryContext.ExecutionStrategy.Execute( - this, static (_, enumerator) => InitializeReader(enumerator), null); - } + _relationalQueryContext.ExecutionStrategy.Execute( + this, static (_, enumerator) => InitializeReader(enumerator), null); + } - var hasNext = _resultCoordinator!.HasNext ?? _dataReader!.Read(); + var hasNext = _resultCoordinator!.HasNext ?? _dataReader!.Read(); - if (hasNext) + if (hasNext) + { + var key = _keySelector(_relationalQueryContext, _dbDataReader!); + var keyIdentifier = _keyIdentifier(_relationalQueryContext, _dbDataReader!); + var group = new InternalGrouping(key); + do { - var key = _keySelector(_relationalQueryContext, _dbDataReader!); - var keyIdentifier = _keyIdentifier(_relationalQueryContext, _dbDataReader!); - var group = new InternalGrouping(key); - do + _resultCoordinator.HasNext = null; + _resultCoordinator!.ResultContext.Values = null; + var element = _elementSelector( + _relationalQueryContext, _dbDataReader!, _resultCoordinator.ResultContext, _resultCoordinator); + if (_relatedDataLoaders != null) { - _resultCoordinator.HasNext = null; - _resultCoordinator!.ResultContext.Values = null; - var element = _elementSelector( + _relatedDataLoaders.Invoke( + _relationalQueryContext, _relationalQueryContext.ExecutionStrategy, _resultCoordinator); + element = _elementSelector( _relationalQueryContext, _dbDataReader!, _resultCoordinator.ResultContext, _resultCoordinator); - if (_relatedDataLoaders != null) - { - _relatedDataLoaders.Invoke( - _relationalQueryContext, _relationalQueryContext.ExecutionStrategy, _resultCoordinator); - element = _elementSelector( - _relationalQueryContext, _dbDataReader!, _resultCoordinator.ResultContext, _resultCoordinator); - } + } - group.Add(element); + group.Add(element); - if (_resultCoordinator!.HasNext ?? _dbDataReader!.Read()) - { - // Check if grouping key changed - if (!CompareIdentifiers( - _keyIdentifierValueComparers, keyIdentifier, - _keyIdentifier(_relationalQueryContext, _dbDataReader!))) - { - _resultCoordinator.HasNext = true; - Current = group; - break; - } - } - else + if (_resultCoordinator!.HasNext ?? _dbDataReader!.Read()) + { + // Check if grouping key changed + if (!CompareIdentifiers( + _keyIdentifierValueComparers, keyIdentifier, + _keyIdentifier(_relationalQueryContext, _dbDataReader!))) { - // End of enumeration + _resultCoordinator.HasNext = true; Current = group; break; } } - while (true); - } - else - { - Current = default!; + else + { + // End of enumeration + Current = group; + break; + } } - - return hasNext; + while (true); } - finally + else { - _concurrencyDetector?.ExitCriticalSection(); + Current = default!; } + + return hasNext; } catch (Exception exception) { @@ -428,76 +421,69 @@ public async ValueTask MoveNextAsync() { try { - _concurrencyDetector?.EnterCriticalSection(); + using var _ = _concurrencyDetector?.EnterCriticalSection(); - try + if (_dataReader == null) { - if (_dataReader == null) - { - await _relationalQueryContext.ExecutionStrategy.ExecuteAsync( - this, - static (_, enumerator, cancellationToken) => InitializeReaderAsync(enumerator, cancellationToken), - null, - _cancellationToken) - .ConfigureAwait(false); - } + await _relationalQueryContext.ExecutionStrategy.ExecuteAsync( + this, + static (_, enumerator, cancellationToken) => InitializeReaderAsync(enumerator, cancellationToken), + null, + _cancellationToken) + .ConfigureAwait(false); + } - var hasNext = _resultCoordinator!.HasNext ?? await _dataReader!.ReadAsync(_cancellationToken).ConfigureAwait(false); + var hasNext = _resultCoordinator!.HasNext ?? await _dataReader!.ReadAsync(_cancellationToken).ConfigureAwait(false); - if (hasNext) + if (hasNext) + { + var key = _keySelector(_relationalQueryContext, _dbDataReader!); + var keyIdentifier = _keyIdentifier(_relationalQueryContext, _dbDataReader!); + var group = new InternalGrouping(key); + do { - var key = _keySelector(_relationalQueryContext, _dbDataReader!); - var keyIdentifier = _keyIdentifier(_relationalQueryContext, _dbDataReader!); - var group = new InternalGrouping(key); - do + _resultCoordinator.HasNext = null; + _resultCoordinator!.ResultContext.Values = null; + var element = _elementSelector( + _relationalQueryContext, _dbDataReader!, _resultCoordinator.ResultContext, _resultCoordinator); + if (_relatedDataLoaders != null) { - _resultCoordinator.HasNext = null; - _resultCoordinator!.ResultContext.Values = null; - var element = _elementSelector( + await _relatedDataLoaders( + _relationalQueryContext, _relationalQueryContext.ExecutionStrategy, _resultCoordinator) + .ConfigureAwait(false); + element = _elementSelector( _relationalQueryContext, _dbDataReader!, _resultCoordinator.ResultContext, _resultCoordinator); - if (_relatedDataLoaders != null) - { - await _relatedDataLoaders( - _relationalQueryContext, _relationalQueryContext.ExecutionStrategy, _resultCoordinator) - .ConfigureAwait(false); - element = _elementSelector( - _relationalQueryContext, _dbDataReader!, _resultCoordinator.ResultContext, _resultCoordinator); - } + } - group.Add(element); + group.Add(element); - if (_resultCoordinator!.HasNext ?? await _dataReader!.ReadAsync(_cancellationToken).ConfigureAwait(false)) - { - // Check if grouping key changed - if (!CompareIdentifiers( - _keyIdentifierValueComparers, keyIdentifier, - _keyIdentifier(_relationalQueryContext, _dbDataReader!))) - { - _resultCoordinator.HasNext = true; - Current = group; - break; - } - } - else + if (_resultCoordinator!.HasNext ?? await _dataReader!.ReadAsync(_cancellationToken).ConfigureAwait(false)) + { + // Check if grouping key changed + if (!CompareIdentifiers( + _keyIdentifierValueComparers, keyIdentifier, + _keyIdentifier(_relationalQueryContext, _dbDataReader!))) { - // End of enumeration + _resultCoordinator.HasNext = true; Current = group; break; } } - while (true); - } - else - { - Current = default!; + else + { + // End of enumeration + Current = group; + break; + } } - - return hasNext; + while (true); } - finally + else { - _concurrencyDetector?.ExitCriticalSection(); + Current = default!; } + + return hasNext; } catch (Exception exception) { diff --git a/src/EFCore.Relational/Query/Internal/SingleQueryingEnumerable.cs b/src/EFCore.Relational/Query/Internal/SingleQueryingEnumerable.cs index 84115479263..d3037ae67f8 100644 --- a/src/EFCore.Relational/Query/Internal/SingleQueryingEnumerable.cs +++ b/src/EFCore.Relational/Query/Internal/SingleQueryingEnumerable.cs @@ -191,62 +191,55 @@ public bool MoveNext() { try { - _concurrencyDetector?.EnterCriticalSection(); + using var _ = _concurrencyDetector?.EnterCriticalSection(); - try + if (_dataReader == null) { - if (_dataReader == null) - { - _relationalQueryContext.ExecutionStrategy.Execute( - this, static (_, enumerator) => InitializeReader(enumerator), null); - } + _relationalQueryContext.ExecutionStrategy.Execute( + this, static (_, enumerator) => InitializeReader(enumerator), null); + } - var hasNext = _resultCoordinator!.HasNext ?? _dataReader!.Read(); + var hasNext = _resultCoordinator!.HasNext ?? _dataReader!.Read(); - if (hasNext) + if (hasNext) + { + while (true) { - while (true) + _resultCoordinator.ResultReady = true; + _resultCoordinator.HasNext = null; + Current = _shaper( + _relationalQueryContext, _dbDataReader!, _resultCoordinator.ResultContext, _resultCoordinator); + if (_resultCoordinator.ResultReady) + { + // We generated a result so null out previously stored values + _resultCoordinator.ResultContext.Values = null; + break; + } + + // If we are already pointing to next row, we don't need to call Read + if (_resultCoordinator.HasNext == true) + { + continue; + } + + if (!_dataReader!.Read()) { + _resultCoordinator.HasNext = false; + // Enumeration has ended, materialize last element _resultCoordinator.ResultReady = true; - _resultCoordinator.HasNext = null; Current = _shaper( _relationalQueryContext, _dbDataReader!, _resultCoordinator.ResultContext, _resultCoordinator); - if (_resultCoordinator.ResultReady) - { - // We generated a result so null out previously stored values - _resultCoordinator.ResultContext.Values = null; - break; - } - - // If we are already pointing to next row, we don't need to call Read - if (_resultCoordinator.HasNext == true) - { - continue; - } - - if (!_dataReader!.Read()) - { - _resultCoordinator.HasNext = false; - // Enumeration has ended, materialize last element - _resultCoordinator.ResultReady = true; - Current = _shaper( - _relationalQueryContext, _dbDataReader!, _resultCoordinator.ResultContext, _resultCoordinator); - - break; - } + + break; } } - else - { - Current = default!; - } - - return hasNext; } - finally + else { - _concurrencyDetector?.ExitCriticalSection(); + Current = default!; } + + return hasNext; } catch (Exception exception) { @@ -347,67 +340,60 @@ public async ValueTask MoveNextAsync() { try { - _concurrencyDetector?.EnterCriticalSection(); + using var _ = _concurrencyDetector?.EnterCriticalSection(); - try + if (_dataReader == null) { - if (_dataReader == null) - { - await _relationalQueryContext.ExecutionStrategy.ExecuteAsync( - this, - static (_, enumerator, cancellationToken) => InitializeReaderAsync(enumerator, cancellationToken), - null, - _cancellationToken) - .ConfigureAwait(false); - } + await _relationalQueryContext.ExecutionStrategy.ExecuteAsync( + this, + static (_, enumerator, cancellationToken) => InitializeReaderAsync(enumerator, cancellationToken), + null, + _cancellationToken) + .ConfigureAwait(false); + } - var hasNext = _resultCoordinator!.HasNext - ?? await _dataReader!.ReadAsync(_cancellationToken).ConfigureAwait(false); + var hasNext = _resultCoordinator!.HasNext + ?? await _dataReader!.ReadAsync(_cancellationToken).ConfigureAwait(false); - if (hasNext) + if (hasNext) + { + while (true) { - while (true) + _resultCoordinator.ResultReady = true; + _resultCoordinator.HasNext = null; + Current = _shaper( + _relationalQueryContext, _dbDataReader!, _resultCoordinator.ResultContext, _resultCoordinator); + if (_resultCoordinator.ResultReady) + { + // We generated a result so null out previously stored values + _resultCoordinator.ResultContext.Values = null; + break; + } + + // If we are already pointing to next row, we don't need to call Read + if (_resultCoordinator.HasNext == true) + { + continue; + } + + if (!await _dataReader!.ReadAsync(_cancellationToken).ConfigureAwait(false)) { + _resultCoordinator.HasNext = false; + // Enumeration has ended, materialize last element _resultCoordinator.ResultReady = true; - _resultCoordinator.HasNext = null; Current = _shaper( _relationalQueryContext, _dbDataReader!, _resultCoordinator.ResultContext, _resultCoordinator); - if (_resultCoordinator.ResultReady) - { - // We generated a result so null out previously stored values - _resultCoordinator.ResultContext.Values = null; - break; - } - - // If we are already pointing to next row, we don't need to call Read - if (_resultCoordinator.HasNext == true) - { - continue; - } - - if (!await _dataReader!.ReadAsync(_cancellationToken).ConfigureAwait(false)) - { - _resultCoordinator.HasNext = false; - // Enumeration has ended, materialize last element - _resultCoordinator.ResultReady = true; - Current = _shaper( - _relationalQueryContext, _dbDataReader!, _resultCoordinator.ResultContext, _resultCoordinator); - - break; - } + + break; } } - else - { - Current = default!; - } - - return hasNext; } - finally + else { - _concurrencyDetector?.ExitCriticalSection(); + Current = default!; } + + return hasNext; } catch (Exception exception) { diff --git a/src/EFCore.Relational/Query/Internal/SplitQueryingEnumerable.cs b/src/EFCore.Relational/Query/Internal/SplitQueryingEnumerable.cs index e50f96ea72b..5a8e99b477c 100644 --- a/src/EFCore.Relational/Query/Internal/SplitQueryingEnumerable.cs +++ b/src/EFCore.Relational/Query/Internal/SplitQueryingEnumerable.cs @@ -205,42 +205,35 @@ public bool MoveNext() { try { - _concurrencyDetector?.EnterCriticalSection(); + using var _ = _concurrencyDetector?.EnterCriticalSection(); - try + if (_dataReader == null) { - if (_dataReader == null) - { - _relationalQueryContext.ExecutionStrategy.Execute( - this, static (_, enumerator) => InitializeReader(enumerator), null); - } + _relationalQueryContext.ExecutionStrategy.Execute( + this, static (_, enumerator) => InitializeReader(enumerator), null); + } - var hasNext = _dataReader!.Read(); + var hasNext = _dataReader!.Read(); - if (hasNext) + if (hasNext) + { + _resultCoordinator!.ResultContext.Values = null; + Current = _shaper( + _relationalQueryContext, _dbDataReader!, _resultCoordinator.ResultContext, _resultCoordinator); + if (_relatedDataLoaders != null) { - _resultCoordinator!.ResultContext.Values = null; + _relatedDataLoaders.Invoke( + _relationalQueryContext, _relationalQueryContext.ExecutionStrategy, _resultCoordinator); Current = _shaper( _relationalQueryContext, _dbDataReader!, _resultCoordinator.ResultContext, _resultCoordinator); - if (_relatedDataLoaders != null) - { - _relatedDataLoaders.Invoke( - _relationalQueryContext, _relationalQueryContext.ExecutionStrategy, _resultCoordinator); - Current = _shaper( - _relationalQueryContext, _dbDataReader!, _resultCoordinator.ResultContext, _resultCoordinator); - } } - else - { - Current = default!; - } - - return hasNext; } - finally + else { - _concurrencyDetector?.ExitCriticalSection(); + Current = default!; } + + return hasNext; } catch (Exception exception) { @@ -355,47 +348,40 @@ public async ValueTask MoveNextAsync() { try { - _concurrencyDetector?.EnterCriticalSection(); + using var _ = _concurrencyDetector?.EnterCriticalSection(); - try + if (_dataReader == null) { - if (_dataReader == null) - { - await _relationalQueryContext.ExecutionStrategy.ExecuteAsync( - this, - static (_, enumerator, cancellationToken) => InitializeReaderAsync(enumerator, cancellationToken), - null, - _cancellationToken) - .ConfigureAwait(false); - } + await _relationalQueryContext.ExecutionStrategy.ExecuteAsync( + this, + static (_, enumerator, cancellationToken) => InitializeReaderAsync(enumerator, cancellationToken), + null, + _cancellationToken) + .ConfigureAwait(false); + } - var hasNext = await _dataReader!.ReadAsync(_cancellationToken).ConfigureAwait(false); + var hasNext = await _dataReader!.ReadAsync(_cancellationToken).ConfigureAwait(false); - if (hasNext) - { - _resultCoordinator!.ResultContext.Values = null; - Current = _shaper( - _relationalQueryContext, _dbDataReader!, _resultCoordinator.ResultContext, _resultCoordinator); - if (_relatedDataLoaders != null) - { - await _relatedDataLoaders( - _relationalQueryContext, _relationalQueryContext.ExecutionStrategy, _resultCoordinator) - .ConfigureAwait(false); - Current = - _shaper(_relationalQueryContext, _dbDataReader!, _resultCoordinator.ResultContext, _resultCoordinator); - } - } - else + if (hasNext) + { + _resultCoordinator!.ResultContext.Values = null; + Current = _shaper( + _relationalQueryContext, _dbDataReader!, _resultCoordinator.ResultContext, _resultCoordinator); + if (_relatedDataLoaders != null) { - Current = default!; + await _relatedDataLoaders( + _relationalQueryContext, _relationalQueryContext.ExecutionStrategy, _resultCoordinator) + .ConfigureAwait(false); + Current = + _shaper(_relationalQueryContext, _dbDataReader!, _resultCoordinator.ResultContext, _resultCoordinator); } - - return hasNext; } - finally + else { - _concurrencyDetector?.ExitCriticalSection(); + Current = default!; } + + return hasNext; } catch (Exception exception) { diff --git a/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.cs b/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.cs index 1d02bce8555..5aefe0b8192 100644 --- a/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.cs +++ b/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.cs @@ -133,39 +133,28 @@ public static int NonQueryResult( { try { - if (threadSafetyChecksEnabled) - { - relationalQueryContext.ConcurrencyDetector.EnterCriticalSection(); - } + using var _ = threadSafetyChecksEnabled + ? (ConcurrencyDetectorCriticalSectionDisposer?)relationalQueryContext.ConcurrencyDetector.EnterCriticalSection() + : null; - try - { - return relationalQueryContext.ExecutionStrategy.Execute( - (relationalQueryContext, relationalCommandResolver, commandSource), - static (_, state) => - { - EntityFrameworkMetricsData.ReportQueryExecuting(); - - var relationalCommand = state.relationalCommandResolver.RentAndPopulateRelationalCommand(state.relationalQueryContext); - - return relationalCommand.ExecuteNonQuery( - new RelationalCommandParameterObject( - state.relationalQueryContext.Connection, - state.relationalQueryContext.ParameterValues, - null, - state.relationalQueryContext.Context, - state.relationalQueryContext.CommandLogger, - state.commandSource)); - }, - null); - } - finally - { - if (threadSafetyChecksEnabled) + return relationalQueryContext.ExecutionStrategy.Execute( + (relationalQueryContext, relationalCommandResolver, commandSource), + static (_, state) => { - relationalQueryContext.ConcurrencyDetector.ExitCriticalSection(); - } - } + EntityFrameworkMetricsData.ReportQueryExecuting(); + + var relationalCommand = state.relationalCommandResolver.RentAndPopulateRelationalCommand(state.relationalQueryContext); + + return relationalCommand.ExecuteNonQuery( + new RelationalCommandParameterObject( + state.relationalQueryContext.Connection, + state.relationalQueryContext.ParameterValues, + null, + state.relationalQueryContext.Context, + state.relationalQueryContext.CommandLogger, + state.commandSource)); + }, + null); } catch (Exception exception) { @@ -211,41 +200,30 @@ public static Task NonQueryResultAsync( { try { - if (threadSafetyChecksEnabled) - { - relationalQueryContext.ConcurrencyDetector.EnterCriticalSection(); - } + using var _ = threadSafetyChecksEnabled + ? (ConcurrencyDetectorCriticalSectionDisposer?)relationalQueryContext.ConcurrencyDetector.EnterCriticalSection() + : null; - try - { - return relationalQueryContext.ExecutionStrategy.ExecuteAsync( - (relationalQueryContext, relationalCommandResolver, commandSource), - static (_, state, cancellationToken) => - { - EntityFrameworkMetricsData.ReportQueryExecuting(); - - var relationalCommand = state.relationalCommandResolver.RentAndPopulateRelationalCommand(state.relationalQueryContext); - - return relationalCommand.ExecuteNonQueryAsync( - new RelationalCommandParameterObject( - state.relationalQueryContext.Connection, - state.relationalQueryContext.ParameterValues, - null, - state.relationalQueryContext.Context, - state.relationalQueryContext.CommandLogger, - state.commandSource), - cancellationToken); - }, - null, - relationalQueryContext.CancellationToken); - } - finally - { - if (threadSafetyChecksEnabled) + return relationalQueryContext.ExecutionStrategy.ExecuteAsync( + (relationalQueryContext, relationalCommandResolver, commandSource), + static (_, state, cancellationToken) => { - relationalQueryContext.ConcurrencyDetector.ExitCriticalSection(); - } - } + EntityFrameworkMetricsData.ReportQueryExecuting(); + + var relationalCommand = state.relationalCommandResolver.RentAndPopulateRelationalCommand(state.relationalQueryContext); + + return relationalCommand.ExecuteNonQueryAsync( + new RelationalCommandParameterObject( + state.relationalQueryContext.Connection, + state.relationalQueryContext.ParameterValues, + null, + state.relationalQueryContext.Context, + state.relationalQueryContext.CommandLogger, + state.commandSource), + cancellationToken); + }, + null, + relationalQueryContext.CancellationToken); } catch (Exception exception) { diff --git a/src/EFCore/ChangeTracking/Internal/StateManager.cs b/src/EFCore/ChangeTracking/Internal/StateManager.cs index af7a640629d..8ce4bc0a536 100644 --- a/src/EFCore/ChangeTracking/Internal/StateManager.cs +++ b/src/EFCore/ChangeTracking/Internal/StateManager.cs @@ -1278,18 +1278,11 @@ private static bool KeyValuesEqual(IProperty property, object? value, object? cu /// protected virtual int SaveChanges(IList entriesToSave) { - _concurrencyDetector?.EnterCriticalSection(); + using var _ = _concurrencyDetector?.EnterCriticalSection(); - try - { - EntityFrameworkMetricsData.ReportSavingChanges(); + EntityFrameworkMetricsData.ReportSavingChanges(); - return _database.SaveChanges(entriesToSave); - } - finally - { - _concurrencyDetector?.ExitCriticalSection(); - } + return _database.SaveChanges(entriesToSave); } /// @@ -1302,19 +1295,12 @@ protected virtual async Task SaveChangesAsync( IList entriesToSave, CancellationToken cancellationToken = default) { - _concurrencyDetector?.EnterCriticalSection(); + using var _ = _concurrencyDetector?.EnterCriticalSection(); - try - { - EntityFrameworkMetricsData.ReportSavingChanges(); + EntityFrameworkMetricsData.ReportSavingChanges(); - return await _database.SaveChangesAsync(entriesToSave, cancellationToken) - .ConfigureAwait(false); - } - finally - { - _concurrencyDetector?.ExitCriticalSection(); - } + return await _database.SaveChangesAsync(entriesToSave, cancellationToken) + .ConfigureAwait(false); } ///