diff --git a/src/EFCore.Cosmos/Infrastructure/CosmosDbContextOptionsBuilder.cs b/src/EFCore.Cosmos/Infrastructure/CosmosDbContextOptionsBuilder.cs
index c8c42564b38..2e9372d0d7c 100644
--- a/src/EFCore.Cosmos/Infrastructure/CosmosDbContextOptionsBuilder.cs
+++ b/src/EFCore.Cosmos/Infrastructure/CosmosDbContextOptionsBuilder.cs
@@ -120,6 +120,15 @@ public virtual CosmosDbContextOptionsBuilder MaxTcpConnectionsPerEndpoint(int co
public virtual CosmosDbContextOptionsBuilder MaxRequestsPerTcpConnection(int requestLimit)
=> WithOption(e => e.WithMaxRequestsPerTcpConnection(Check.NotNull(requestLimit, nameof(requestLimit))));
+ ///
+ /// Sets the boolean to only return the headers and status code in the Cosmos DB response for write item operation
+ /// like Create, Upsert, Patch and Replace. Setting the option to false will cause the response to have a null resource.
+ /// This reduces networking and CPU load by not sending the resource back over the network and serializing it on the client.
+ ///
+ /// to have null resource
+ public virtual CosmosDbContextOptionsBuilder ContentResponseOnWriteEnabled(bool enabled = false)
+ => WithOption(e => e.ContentResponseOnWriteEnabled(Check.NotNull(enabled, nameof(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 3309d3bc01a..33e8ed59405 100644
--- a/src/EFCore.Cosmos/Infrastructure/Internal/CosmosDbOptionExtension.cs
+++ b/src/EFCore.Cosmos/Infrastructure/Internal/CosmosDbOptionExtension.cs
@@ -39,6 +39,7 @@ public class CosmosOptionsExtension : IDbContextOptionsExtension
private int? _gatewayModeMaxConnectionLimit;
private int? _maxTcpConnectionsPerEndpoint;
private int? _maxRequestsPerTcpConnection;
+ private bool? _enableContentResponseOnWrite;
private DbContextOptionsExtensionInfo _info;
///
@@ -74,6 +75,7 @@ protected CosmosOptionsExtension([NotNull] CosmosOptionsExtension copyFrom)
_gatewayModeMaxConnectionLimit = copyFrom._gatewayModeMaxConnectionLimit;
_maxTcpConnectionsPerEndpoint = copyFrom._maxTcpConnectionsPerEndpoint;
_maxRequestsPerTcpConnection = copyFrom._maxRequestsPerTcpConnection;
+ _enableContentResponseOnWrite = copyFrom._enableContentResponseOnWrite;
}
///
@@ -441,6 +443,30 @@ public virtual CosmosOptionsExtension WithMaxRequestsPerTcpConnection(int reques
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? EnableContentResponseOnWrite
+ => _enableContentResponseOnWrite;
+
+ ///
+ /// 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 ContentResponseOnWriteEnabled(bool enabled)
+ {
+ var clone = Clone();
+
+ clone._enableContentResponseOnWrite = enabled;
+
+ return clone;
+ }
+
///
/// A factory for creating the default , or if none has been
/// configured.
diff --git a/src/EFCore.Cosmos/Infrastructure/Internal/CosmosSingletonOptions.cs b/src/EFCore.Cosmos/Infrastructure/Internal/CosmosSingletonOptions.cs
index d597da75d6b..4dc74bcd955 100644
--- a/src/EFCore.Cosmos/Infrastructure/Internal/CosmosSingletonOptions.cs
+++ b/src/EFCore.Cosmos/Infrastructure/Internal/CosmosSingletonOptions.cs
@@ -129,6 +129,14 @@ public class CosmosSingletonOptions : ICosmosSingletonOptions
///
public virtual int? MaxRequestsPerTcpConnection { 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? EnableContentResponseOnWrite { 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
@@ -153,6 +161,7 @@ public virtual void Initialize(IDbContextOptions options)
GatewayModeMaxConnectionLimit = cosmosOptions.GatewayModeMaxConnectionLimit;
MaxTcpConnectionsPerEndpoint = cosmosOptions.MaxTcpConnectionsPerEndpoint;
MaxRequestsPerTcpConnection = cosmosOptions.MaxRequestsPerTcpConnection;
+ EnableContentResponseOnWrite = cosmosOptions.EnableContentResponseOnWrite;
}
}
@@ -179,7 +188,9 @@ public virtual void Validate(IDbContextOptions options)
|| IdleTcpConnectionTimeout != cosmosOptions.IdleTcpConnectionTimeout
|| GatewayModeMaxConnectionLimit != cosmosOptions.GatewayModeMaxConnectionLimit
|| MaxTcpConnectionsPerEndpoint != cosmosOptions.MaxTcpConnectionsPerEndpoint
- || MaxRequestsPerTcpConnection != cosmosOptions.MaxRequestsPerTcpConnection))
+ || MaxRequestsPerTcpConnection != cosmosOptions.MaxRequestsPerTcpConnection
+ || EnableContentResponseOnWrite != cosmosOptions.EnableContentResponseOnWrite
+ ))
{
throw new InvalidOperationException(
CoreStrings.SingletonOptionChanged(
diff --git a/src/EFCore.Cosmos/Infrastructure/Internal/ICosmosSingletonOptions.cs b/src/EFCore.Cosmos/Infrastructure/Internal/ICosmosSingletonOptions.cs
index df14c951248..df2df047861 100644
--- a/src/EFCore.Cosmos/Infrastructure/Internal/ICosmosSingletonOptions.cs
+++ b/src/EFCore.Cosmos/Infrastructure/Internal/ICosmosSingletonOptions.cs
@@ -128,5 +128,14 @@ public interface ICosmosSingletonOptions : ISingletonOptions
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
int? MaxRequestsPerTcpConnection { 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? EnableContentResponseOnWrite { get; }
}
}
diff --git a/src/EFCore.Cosmos/Storage/Internal/CosmosClientWrapper.cs b/src/EFCore.Cosmos/Storage/Internal/CosmosClientWrapper.cs
index 1342182e7a2..c7c4d247814 100644
--- a/src/EFCore.Cosmos/Storage/Internal/CosmosClientWrapper.cs
+++ b/src/EFCore.Cosmos/Storage/Internal/CosmosClientWrapper.cs
@@ -292,7 +292,8 @@ private async Task CreateItemOnceAsync(
var entry = parameters.Entry;
var container = Client.GetDatabase(_databaseId).GetContainer(parameters.ContainerId);
- var itemRequestOptions = CreateItemRequestOptions(entry);
+ var enableContentResponseOnWrite = ((ICosmosSingletonOptions)Client.ClientOptions).EnableContentResponseOnWrite;
+ var itemRequestOptions = CreateItemRequestOptions(entry, enableContentResponseOnWrite);
var partitionKey = CreatePartitionKey(entry);
using var response = await container.CreateItemStreamAsync(stream, partitionKey, itemRequestOptions, cancellationToken)
@@ -354,7 +355,10 @@ private async Task ReplaceItemOnceAsync(
var entry = parameters.Entry;
var container = Client.GetDatabase(_databaseId).GetContainer(parameters.ContainerId);
- var itemRequestOptions = CreateItemRequestOptions(entry);
+
+ var enableContentResponseOnWrite = ((ICosmosSingletonOptions)Client.ClientOptions).EnableContentResponseOnWrite;
+ var itemRequestOptions = CreateItemRequestOptions(entry, enableContentResponseOnWrite);
+
var partitionKey = CreatePartitionKey(entry);
using var response = await container.ReplaceItemStreamAsync(
@@ -416,7 +420,10 @@ public virtual async Task DeleteItemOnceAsync(
{
var entry = parameters.Entry;
var items = Client.GetDatabase(_databaseId).GetContainer(parameters.ContainerId);
- var itemRequestOptions = CreateItemRequestOptions(entry);
+
+ var enableContentResponseOnWrite = ((ICosmosSingletonOptions)Client.ClientOptions).EnableContentResponseOnWrite;
+
+ var itemRequestOptions = CreateItemRequestOptions(entry, enableContentResponseOnWrite);
var partitionKey = CreatePartitionKey(entry);
using var response = await items.DeleteItemStreamAsync(
@@ -427,7 +434,7 @@ public virtual async Task DeleteItemOnceAsync(
return response.StatusCode == HttpStatusCode.NoContent;
}
- private static ItemRequestOptions CreateItemRequestOptions(IUpdateEntry entry)
+ private static ItemRequestOptions CreateItemRequestOptions(IUpdateEntry entry, bool? enableContentResponseOnWrite)
{
var etagProperty = entry.EntityType.GetETagProperty();
if (etagProperty == null)
@@ -442,7 +449,9 @@ private static ItemRequestOptions CreateItemRequestOptions(IUpdateEntry entry)
etag = converter.ConvertToProvider(etag);
}
- return new ItemRequestOptions { IfMatchEtag = (string)etag };
+
+
+ return new ItemRequestOptions { IfMatchEtag = (string)etag, EnableContentResponseOnWrite = enableContentResponseOnWrite };
}
private static PartitionKey CreatePartitionKey(IUpdateEntry entry)
diff --git a/src/EFCore.Cosmos/Storage/Internal/SingletonCosmosClientWrapper.cs b/src/EFCore.Cosmos/Storage/Internal/SingletonCosmosClientWrapper.cs
index 00a33e26fe4..217a0c520d6 100644
--- a/src/EFCore.Cosmos/Storage/Internal/SingletonCosmosClientWrapper.cs
+++ b/src/EFCore.Cosmos/Storage/Internal/SingletonCosmosClientWrapper.cs
@@ -96,6 +96,11 @@ public SingletonCosmosClientWrapper([NotNull] ICosmosSingletonOptions options)
configuration.MaxRequestsPerTcpConnection = options.MaxRequestsPerTcpConnection.Value;
}
+ if (options.EnableContentResponseOnWrite != null)
+ {
+ configuration.EnableTcpConnectionEndpointRediscovery = options.EnableContentResponseOnWrite.Value;
+ }
+
_options = configuration;
}
diff --git a/test/EFCore.Cosmos.Tests/Extensions/CosmosDbContextOptionsExtensionsTests.cs b/test/EFCore.Cosmos.Tests/Extensions/CosmosDbContextOptionsExtensionsTests.cs
index 311d18b9ada..0030557a2b1 100644
--- a/test/EFCore.Cosmos.Tests/Extensions/CosmosDbContextOptionsExtensionsTests.cs
+++ b/test/EFCore.Cosmos.Tests/Extensions/CosmosDbContextOptionsExtensionsTests.cs
@@ -191,5 +191,20 @@ public void Can_create_options_with_max_requests_per_tcp_connection()
Assert.Equal(requestLimit, extension.MaxRequestsPerTcpConnection);
}
+
+ [ConditionalFact]
+ public void Can_create_options_with_content_response_on_write_enabled()
+ {
+ var enabled = true;
+ var options = new DbContextOptionsBuilder().UseCosmos(
+ "serviceEndPoint",
+ "authKeyOrResourceToken",
+ "databaseName",
+ o => { o.ContentResponseOnWriteEnabled(enabled); });
+
+ var extension = options.Options.FindExtension();
+
+ Assert.Equal(enabled, extension.EnableContentResponseOnWrite);
+ }
}
}