Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -211,6 +212,22 @@ public virtual CosmosDbContextOptionsBuilder MaxRequestsPerTcpConnection(int req
public virtual CosmosDbContextOptionsBuilder ContentResponseOnWriteEnabled(bool enabled = true)
=> WithOption(e => e.ContentResponseOnWriteEnabled(Check.NotNull(enabled)));

/// <summary>
/// Sets the boolean to enable the <see href="https://learn.microsoft.com/en-us/azure/cosmos-db/bulk-executor-overview">Cosmos DB SDK bulk execution feature</see>.
/// 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 <see href="https://learn.microsoft.com/en-us/azure/cosmos-db/nosql/transactional-batch">Transactional Batches</see> 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 <see cref="AutoTransactionBehavior.Never"/>.
/// For more information, see <see href="https://learn.microsoft.com/en-us/ef/core/providers/cosmos/saving">Saving Data - Azure Cosmos DB Provider</see>.
/// </summary>
/// <remarks>
/// See <see href="https://aka.ms/efcore-docs-dbcontext-options">Using DbContextOptions</see>, and
/// <see href="https://aka.ms/efcore-docs-cosmos">Accessing Azure Cosmos DB with EF Core</see> for more information and examples.
/// </remarks>
/// <param name="enabled"><see langword="true" /> to enable the Cosmos DB SDK bulk feature.</param>
public virtual CosmosDbContextOptionsBuilder BulkExecutionEnabled(bool enabled = true)
=> WithOption(e => e.BulkExecutionEnabled(enabled));

/// <summary>
/// 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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public class CosmosOptionsExtension : IDbContextOptionsExtension
private bool? _enableContentResponseOnWrite;
private DbContextOptionsExtensionInfo? _info;
private Func<HttpClient>? _httpClientFactory;
private bool? _enableBulkExecution;

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
Expand Down Expand Up @@ -564,6 +565,29 @@ public virtual CosmosOptionsExtension WithHttpClientFactory(Func<HttpClient>? ht
return clone;
}

/// <summary>
/// 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.
/// </summary>
public virtual bool? EnableBulkExecution => _enableBulkExecution;

/// <summary>
/// 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.
/// </summary>
public virtual CosmosOptionsExtension BulkExecutionEnabled(bool enabled)
{
var clone = Clone();

clone._enableBulkExecution = enabled;

return clone;
}

/// <summary>
/// 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
Expand Down Expand Up @@ -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();
}
Expand All @@ -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<string, string> debugInfo)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,14 @@ public class CosmosSingletonOptions : ICosmosSingletonOptions
/// </summary>
public virtual Func<HttpClient>? HttpClientFactory { get; private set; }

/// <summary>
/// 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.
/// </summary>
public virtual bool? EnableBulkExecution { get; private set; }

/// <summary>
/// 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
Expand Down Expand Up @@ -178,6 +186,7 @@ public virtual void Initialize(IDbContextOptions options)
MaxTcpConnectionsPerEndpoint = cosmosOptions.MaxTcpConnectionsPerEndpoint;
MaxRequestsPerTcpConnection = cosmosOptions.MaxRequestsPerTcpConnection;
HttpClientFactory = cosmosOptions.HttpClientFactory;
EnableBulkExecution = cosmosOptions.EnableBulkExecution;
}
}

Expand Down Expand Up @@ -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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,4 +155,12 @@ public interface ICosmosSingletonOptions : ISingletonOptions
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
Func<HttpClient>? HttpClientFactory { get; }

/// <summary>
/// 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.
/// </summary>
bool? EnableBulkExecution { get; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down