diff --git a/src/EFCore.Cosmos/Infrastructure/CosmosDbContextOptionsBuilder.cs b/src/EFCore.Cosmos/Infrastructure/CosmosDbContextOptionsBuilder.cs
index e88fabf78da..7649f106dbb 100644
--- a/src/EFCore.Cosmos/Infrastructure/CosmosDbContextOptionsBuilder.cs
+++ b/src/EFCore.Cosmos/Infrastructure/CosmosDbContextOptionsBuilder.cs
@@ -4,6 +4,7 @@
using System.ComponentModel;
using System.Net;
using Microsoft.EntityFrameworkCore.Cosmos.Infrastructure.Internal;
+using static System.Net.WebRequestMethods;
namespace Microsoft.EntityFrameworkCore.Infrastructure;
@@ -211,6 +212,22 @@ public virtual CosmosDbContextOptionsBuilder MaxRequestsPerTcpConnection(int req
public virtual CosmosDbContextOptionsBuilder ContentResponseOnWriteEnabled(bool enabled = true)
=> WithOption(e => e.ContentResponseOnWriteEnabled(Check.NotNull(enabled)));
+ ///
+ /// Sets the boolean to enable the Cosmos DB SDK bulk execution feature.
+ /// Enabling this feature can improve throughput for small write operations but may increase latency.
+ /// It is recommended only for high-throughput, non-latency-sensitive scenarios.
+ /// Because Transactional Batches cannot be executed in bulk mode,
+ /// any operations batched by EF will not use bulk execution. To ensure operations are executed in bulk, consider disabling batching by setting .
+ /// For more information, see Saving Data - Azure Cosmos DB Provider.
+ ///
+ ///
+ /// See Using DbContextOptions, and
+ /// Accessing Azure Cosmos DB with EF Core for more information and examples.
+ ///
+ /// to enable the Cosmos DB SDK bulk feature.
+ public virtual CosmosDbContextOptionsBuilder BulkExecutionEnabled(bool enabled = true)
+ => WithOption(e => e.BulkExecutionEnabled(enabled));
+
///
/// Sets an option by cloning the extension used to store the settings. This ensures the builder
/// does not modify options that are already in use elsewhere.
diff --git a/src/EFCore.Cosmos/Infrastructure/Internal/CosmosDbOptionExtension.cs b/src/EFCore.Cosmos/Infrastructure/Internal/CosmosDbOptionExtension.cs
index f2545174ac3..dbc8ac9f993 100644
--- a/src/EFCore.Cosmos/Infrastructure/Internal/CosmosDbOptionExtension.cs
+++ b/src/EFCore.Cosmos/Infrastructure/Internal/CosmosDbOptionExtension.cs
@@ -36,6 +36,7 @@ public class CosmosOptionsExtension : IDbContextOptionsExtension
private bool? _enableContentResponseOnWrite;
private DbContextOptionsExtensionInfo? _info;
private Func? _httpClientFactory;
+ private bool? _enableBulkExecution;
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -564,6 +565,29 @@ public virtual CosmosOptionsExtension WithHttpClientFactory(Func? ht
return clone;
}
+ ///
+ /// 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.
+ ///
+ public virtual bool? EnableBulkExecution => _enableBulkExecution;
+
+ ///
+ /// 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.
+ ///
+ public virtual CosmosOptionsExtension BulkExecutionEnabled(bool enabled)
+ {
+ var clone = Clone();
+
+ clone._enableBulkExecution = enabled;
+
+ return clone;
+ }
+
///
/// 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
@@ -632,6 +656,7 @@ public override int GetServiceProviderHashCode()
hashCode.Add(Extension._maxTcpConnectionsPerEndpoint);
hashCode.Add(Extension._maxRequestsPerTcpConnection);
hashCode.Add(Extension._httpClientFactory);
+ hashCode.Add(Extension._enableBulkExecution);
_serviceProviderHash = hashCode.ToHashCode();
}
@@ -656,7 +681,8 @@ public override bool ShouldUseSameServiceProvider(DbContextOptionsExtensionInfo
&& Extension._gatewayModeMaxConnectionLimit == otherInfo.Extension._gatewayModeMaxConnectionLimit
&& Extension._maxTcpConnectionsPerEndpoint == otherInfo.Extension._maxTcpConnectionsPerEndpoint
&& Extension._maxRequestsPerTcpConnection == otherInfo.Extension._maxRequestsPerTcpConnection
- && Extension._httpClientFactory == otherInfo.Extension._httpClientFactory;
+ && Extension._httpClientFactory == otherInfo.Extension._httpClientFactory
+ && Extension._enableBulkExecution == otherInfo.Extension.EnableBulkExecution;
public override void PopulateDebugInfo(IDictionary debugInfo)
{
diff --git a/src/EFCore.Cosmos/Infrastructure/Internal/CosmosSingletonOptions.cs b/src/EFCore.Cosmos/Infrastructure/Internal/CosmosSingletonOptions.cs
index af29229cfa5..5fa7ae5a2da 100644
--- a/src/EFCore.Cosmos/Infrastructure/Internal/CosmosSingletonOptions.cs
+++ b/src/EFCore.Cosmos/Infrastructure/Internal/CosmosSingletonOptions.cs
@@ -151,6 +151,14 @@ public class CosmosSingletonOptions : ICosmosSingletonOptions
///
public virtual Func? HttpClientFactory { get; private set; }
+ ///
+ /// 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.
+ ///
+ public virtual bool? EnableBulkExecution { get; private set; }
+
///
/// 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
@@ -178,6 +186,7 @@ public virtual void Initialize(IDbContextOptions options)
MaxTcpConnectionsPerEndpoint = cosmosOptions.MaxTcpConnectionsPerEndpoint;
MaxRequestsPerTcpConnection = cosmosOptions.MaxRequestsPerTcpConnection;
HttpClientFactory = cosmosOptions.HttpClientFactory;
+ EnableBulkExecution = cosmosOptions.EnableBulkExecution;
}
}
@@ -208,6 +217,7 @@ public virtual void Validate(IDbContextOptions options)
|| MaxTcpConnectionsPerEndpoint != cosmosOptions.MaxTcpConnectionsPerEndpoint
|| MaxRequestsPerTcpConnection != cosmosOptions.MaxRequestsPerTcpConnection
|| HttpClientFactory != cosmosOptions.HttpClientFactory
+ || EnableBulkExecution != cosmosOptions.EnableBulkExecution
))
{
throw new InvalidOperationException(
diff --git a/src/EFCore.Cosmos/Infrastructure/Internal/ICosmosSingletonOptions.cs b/src/EFCore.Cosmos/Infrastructure/Internal/ICosmosSingletonOptions.cs
index a26b79a82b3..b2d043279fb 100644
--- a/src/EFCore.Cosmos/Infrastructure/Internal/ICosmosSingletonOptions.cs
+++ b/src/EFCore.Cosmos/Infrastructure/Internal/ICosmosSingletonOptions.cs
@@ -155,4 +155,12 @@ public interface ICosmosSingletonOptions : ISingletonOptions
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
Func? HttpClientFactory { get; }
+
+ ///
+ /// 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.
+ ///
+ bool? EnableBulkExecution { get; }
}
diff --git a/src/EFCore.Cosmos/Storage/Internal/SingletonCosmosClientWrapper.cs b/src/EFCore.Cosmos/Storage/Internal/SingletonCosmosClientWrapper.cs
index 38a820e421d..f52ed9ada70 100644
--- a/src/EFCore.Cosmos/Storage/Internal/SingletonCosmosClientWrapper.cs
+++ b/src/EFCore.Cosmos/Storage/Internal/SingletonCosmosClientWrapper.cs
@@ -88,6 +88,11 @@ public SingletonCosmosClientWrapper(ICosmosSingletonOptions options)
configuration.HttpClientFactory = options.HttpClientFactory;
}
+ if (options.EnableBulkExecution != null)
+ {
+ configuration.AllowBulkExecution = options.EnableBulkExecution.Value;
+ }
+
_client = options switch
{
{ ConnectionString: not null and not "" } => new CosmosClient(options.ConnectionString, configuration),
diff --git a/test/EFCore.Cosmos.Tests/Extensions/CosmosDbContextOptionsExtensionsTests.cs b/test/EFCore.Cosmos.Tests/Extensions/CosmosDbContextOptionsExtensionsTests.cs
index 895f45889bf..eb50f35ed8a 100644
--- a/test/EFCore.Cosmos.Tests/Extensions/CosmosDbContextOptionsExtensionsTests.cs
+++ b/test/EFCore.Cosmos.Tests/Extensions/CosmosDbContextOptionsExtensionsTests.cs
@@ -65,6 +65,7 @@ public void Can_create_options_with_valid_values()
Test(o => o.MaxTcpConnectionsPerEndpoint(3), o => Assert.Equal(3, o.MaxTcpConnectionsPerEndpoint));
Test(o => o.LimitToEndpoint(), o => Assert.True(o.LimitToEndpoint));
Test(o => o.ContentResponseOnWriteEnabled(), o => Assert.True(o.EnableContentResponseOnWrite));
+ Test(o => o.BulkExecutionEnabled(), o => Assert.True(o.EnableBulkExecution));
var webProxy = new WebProxy();
Test(o => o.WebProxy(webProxy), o => Assert.Same(webProxy, o.WebProxy));