diff --git a/Src/Couchbase.Linq.IntegrationTests/config.json b/Src/Couchbase.Linq.IntegrationTests/config.json index 9821fdc..268ca71 100644 --- a/Src/Couchbase.Linq.IntegrationTests/config.json +++ b/Src/Couchbase.Linq.IntegrationTests/config.json @@ -2,6 +2,7 @@ "couchbase": { "connectionString": "couchbase://localhost", "username": "Administrator", - "password": "password" + "password": "password", + "enableDnsSrvResolution": false } } diff --git a/Src/Couchbase.Linq.UnitTests/Couchbase.Linq.UnitTests.csproj b/Src/Couchbase.Linq.UnitTests/Couchbase.Linq.UnitTests.csproj index b862aa7..40103bf 100644 --- a/Src/Couchbase.Linq.UnitTests/Couchbase.Linq.UnitTests.csproj +++ b/Src/Couchbase.Linq.UnitTests/Couchbase.Linq.UnitTests.csproj @@ -10,10 +10,10 @@ - - - - + + + + diff --git a/Src/Couchbase.Linq/Couchbase.Linq.csproj b/Src/Couchbase.Linq/Couchbase.Linq.csproj index 8fe535a..83dc444 100644 --- a/Src/Couchbase.Linq/Couchbase.Linq.csproj +++ b/Src/Couchbase.Linq/Couchbase.Linq.csproj @@ -15,6 +15,7 @@ netstandard2.0;net6.0;net8.0 Couchbase.Linq Couchbase.Linq + true true true @@ -33,8 +34,8 @@ - - + + diff --git a/Src/Couchbase.Linq/Execution/ClusterQueryExecutor.cs b/Src/Couchbase.Linq/Execution/ClusterQueryExecutor.cs index ce331fd..452d2c3 100644 --- a/Src/Couchbase.Linq/Execution/ClusterQueryExecutor.cs +++ b/Src/Couchbase.Linq/Execution/ClusterQueryExecutor.cs @@ -106,7 +106,46 @@ public IEnumerable ExecuteCollection(QueryModel queryModel) /// List of objects returned by the request. public IEnumerable ExecuteCollection(string statement, LinqQueryOptions queryOptions) { - return ExecuteCollectionAsync(statement, queryOptions).ToEnumerable(); + // This sync-over-async pattern is not ideal, but necessary for compatibility + var asyncEnumerable = ExecuteCollectionAsync(statement, queryOptions); + + var enumerator = asyncEnumerable.GetAsyncEnumerator(); + try + { + while (BlockingWait(enumerator.MoveNextAsync())) + { + yield return enumerator.Current; + } + } + finally + { + BlockingWait(enumerator.DisposeAsync()); + } + } + + private static void BlockingWait(ValueTask task) + { + if (task.IsCompleted) + { + // Avoid allocating a Task unnecessarily if the ValueTask is already completed + task.GetAwaiter().GetResult(); + return; + } + + // ValueTask must be converted to Task to safely await the result if it is not completed + task.AsTask().GetAwaiter().GetResult(); + } + + private static T BlockingWait(ValueTask task) + { + if (task.IsCompleted) + { + // Avoid allocating a Task unnecessarily if the ValueTask is already completed + return task.GetAwaiter().GetResult(); + } + + // ValueTask must be converted to Task to safely await the result if it is not completed + return task.AsTask().GetAwaiter().GetResult(); } public IAsyncEnumerable ExecuteCollectionAsync(QueryModel queryModel, CancellationToken cancellationToken = default)