From acd1d99fec6b64f6ccda4df8a893bcfa337e8b3c Mon Sep 17 00:00:00 2001 From: Andriy Svyryd Date: Tue, 11 Jan 2022 19:01:46 -0800 Subject: [PATCH] Document Cosmos throughput configuration Document basic support for collections of primitive types in Cosmos Fixes #3597 Fixes #3358 --- .../core/providers/cosmos/index.md | 112 +++++++++++++++++- entity-framework/toc.yml | 2 +- .../CosmosModelConfigurationSample.cs | 6 +- 3 files changed, 115 insertions(+), 5 deletions(-) diff --git a/entity-framework/core/providers/cosmos/index.md b/entity-framework/core/providers/cosmos/index.md index 5ca12f6596..10ec701186 100644 --- a/entity-framework/core/providers/cosmos/index.md +++ b/entity-framework/core/providers/cosmos/index.md @@ -2,7 +2,7 @@ title: Azure Cosmos DB Provider - EF Core description: Documentation for the database provider that allows Entity Framework Core to be used with the Azure Cosmos DB SQL API author: AndriySvyryd -ms.date: 11/15/2021 +ms.date: 01/11/2022 uid: core/providers/cosmos/index --- # EF Core Azure Cosmos DB Provider @@ -103,8 +103,33 @@ Once configured the partition key property should always have a non-null value. It is generally recommended to add the partition key to the primary key as that best reflects the server semantics and allows some optimizations, for example in `FindAsync`. +### Provisioned throughput + +If you use EF Core to create the Azure Cosmos database or containers you can configure [provisioned throughput](/azure/cosmos-db/set-throughput) for the database by calling or . For example: + + +[!code-csharp[ModelThroughput](../../../../samples/core/Miscellaneous/NewInEFCore6.Cosmos/CosmosModelConfigurationSample.cs?name=ModelThroughput)] + +To configure provisioned throughput for a container call or . For example: + + +[!code-csharp[EntityTypeThroughput](../../../../samples/core/Miscellaneous/NewInEFCore6.Cosmos/CosmosModelConfigurationSample.cs?name=EntityTypeThroughput)] + ## Embedded entities +> [!NOTE] +> Beginning with EF Core 6.0 related entity types are configured as owned by default. To prevent this for a specific entity type call . + For Cosmos, owned entities are embedded in the same item as the owner. To change a property name use [ToJsonProperty](/dotnet/api/Microsoft.EntityFrameworkCore.CosmosEntityTypeBuilderExtensions.ToJsonProperty): [!code-csharp[PropertyNames](../../../../samples/core/Cosmos/ModelBuilding/OrderContext.cs?name=PropertyNames)] @@ -169,6 +194,91 @@ Internally EF Core always needs to have unique key values for all tracked entiti > [!TIP] > When necessary the default primary key for the owned entity types can be changed, but then key values should be provided explicitly. +### Collections of primitive types + +Collections of supported primitive types, such as `string` and `int`, are discovered and mapped automatically. Supported collections are all types that implement or . For example, consider this entity type: + + +[!code-csharp[BookEntity](../../../../samples/core/Miscellaneous/NewInEFCore6.Cosmos/CosmosPrimitiveTypesSample.cs?name=BookEntity)] + +Both the list and the dictionary can be populated and inserted into the database in the normal way: + + +[!code-csharp[Insert](../../../../samples/core/Miscellaneous/NewInEFCore6.Cosmos/CosmosPrimitiveTypesSample.cs?name=Insert)] + +This results in the following JSON document: + +```json +{ + "Id": "0b32283e-22a8-4103-bb4f-6052604868bd", + "Discriminator": "Book", + "Notes": { + "36": "The Terracotta Army", + "48": "Saint Mark's Basilica", + "121": "Fridges", + "144": "Peter Higgs" + }, + "Quotes": [ + "Thomas (Tommy) Flowers was the British engineer behind the design of the Colossus computer.", + "Invented originally for Guinness, plastic widgets are nitrogen-filled spheres.", + "For 20 years after its introduction in 1979, the Walkman dominated the personal stereo market." + ], + "Title": "How It Works: Incredible History", + "id": "Book|0b32283e-22a8-4103-bb4f-6052604868bd", + "_rid": "t-E3AIxaencBAAAAAAAAAA==", + "_self": "dbs/t-E3AA==/colls/t-E3AIxaenc=/docs/t-E3AIxaencBAAAAAAAAAA==/", + "_etag": "\"00000000-0000-0000-9b50-fc769dc901d7\"", + "_attachments": "attachments/", + "_ts": 1630075016 +} +``` + +These collections can then be updated, again in the normal way: + + +[!code-csharp[Updates](../../../../samples/core/Miscellaneous/NewInEFCore6.Cosmos/CosmosPrimitiveTypesSample.cs?name=Updates)] + +Limitations: + +* Only dictionaries with string keys are supported +* Querying into the contents of primitive collections is not currently supported. Vote for [#16926](https://github.com/dotnet/efcore/issues/16926), [#25700](https://github.com/dotnet/efcore/issues/25700), and [#25701](https://github.com/dotnet/efcore/issues/25701) if these features are important to you. + ## Working with disconnected entities Every item needs to have an `id` value that is unique for the given partition key. By default EF Core generates the value by concatenating the discriminator and the primary key values, using '|' as a delimiter. The key values are only generated when an entity enters the `Added` state. This might pose a problem when [attaching entities](xref:core/saving/disconnected-entities) if they don't have an `id` property on the .NET type to store the value. diff --git a/entity-framework/toc.yml b/entity-framework/toc.yml index 68895d93cb..563ce99074 100644 --- a/entity-framework/toc.yml +++ b/entity-framework/toc.yml @@ -113,7 +113,7 @@ - name: Overview href: core/dbcontext-configuration/index.md - name: Context pooling - href: core/performance/advanced-performance-topics#dbcontext-pooling + href: core/performance/advanced-performance-topics.md#dbcontext-pooling - name: Create a model items: diff --git a/samples/core/Miscellaneous/NewInEFCore6.Cosmos/CosmosModelConfigurationSample.cs b/samples/core/Miscellaneous/NewInEFCore6.Cosmos/CosmosModelConfigurationSample.cs index 2545d5dbf4..8fa4898b96 100644 --- a/samples/core/Miscellaneous/NewInEFCore6.Cosmos/CosmosModelConfigurationSample.cs +++ b/samples/core/Miscellaneous/NewInEFCore6.Cosmos/CosmosModelConfigurationSample.cs @@ -77,15 +77,15 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) #region ModelThroughput modelBuilder.HasManualThroughput(2000); - modelBuilder.HasAutoscaleThroughput(6000); + modelBuilder.HasAutoscaleThroughput(4000); #endregion #region EntityTypeThroughput modelBuilder.Entity( entityTypeBuilder => { - entityTypeBuilder.HasManualThroughput(3000); - entityTypeBuilder.HasAutoscaleThroughput(12000); + entityTypeBuilder.HasManualThroughput(5000); + entityTypeBuilder.HasAutoscaleThroughput(3000); }); #endregion