Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document Cosmos throughput configuration #3673

Merged
merged 1 commit into from
Jan 12, 2022
Merged
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
112 changes: 111 additions & 1 deletion entity-framework/core/providers/cosmos/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 <xref:Microsoft.EntityFrameworkCore.CosmosModelBuilderExtensions.HasAutoscaleThroughput%2A?displayProperty=nameWithType> or <xref:Microsoft.EntityFrameworkCore.CosmosModelBuilderExtensions.HasManualThroughput%2A?displayProperty=nameWithType>. For example:

<!--
modelBuilder.HasManualThroughput(2000);
modelBuilder.HasAutoscaleThroughput(4000);
-->
[!code-csharp[ModelThroughput](../../../../samples/core/Miscellaneous/NewInEFCore6.Cosmos/CosmosModelConfigurationSample.cs?name=ModelThroughput)]

To configure provisioned throughput for a container call <xref:Microsoft.EntityFrameworkCore.CosmosEntityTypeBuilderExtensions.HasAutoscaleThroughput%2A?displayProperty=nameWithType> or <xref:Microsoft.EntityFrameworkCore.CosmosEntityTypeBuilderExtensions.HasManualThroughput%2A?displayProperty=nameWithType>. For example:

<!--
modelBuilder.Entity<Family>(
entityTypeBuilder =>
{
entityTypeBuilder.HasManualThroughput(5000);
entityTypeBuilder.HasAutoscaleThroughput(3000);
});
-->
[!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 <xref:Microsoft.EntityFrameworkCore.ModelBuilder.Entity%2A?displayProperty=nameWithType>.

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)]
Expand Down Expand Up @@ -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 <xref:System.Collections.Generic.IReadOnlyList%601> or <xref:System.Collections.Generic.IReadOnlyDictionary%602>. For example, consider this entity type:

<!--
public class Book
{
public Guid Id { get; set; }
public string Title { get; set; }
public IList<string> Quotes { get; set; }
public IDictionary<string, string> Notes { get; set; }
}
-->
[!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:

<!--
using var context = new BooksContext();

var book = new Book
{
Title = "How It Works: Incredible History",
Quotes = new List<string>
{
"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."
},
Notes = new Dictionary<string, string>
{
{ "121", "Fridges" },
{ "144", "Peter Higgs" },
{ "48", "Saint Mark's Basilica" },
{ "36", "The Terracotta Army" }
}
};

context.Add(book);
context.SaveChanges();
-->
[!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:

<!--
book.Quotes.Add("Pressing the emergency button lowered the rods again.");
book.Notes["48"] = "Chiesa d'Oro";

context.SaveChanges();
-->
[!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.
Expand Down
2 changes: 1 addition & 1 deletion entity-framework/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<Family>(
entityTypeBuilder =>
{
entityTypeBuilder.HasManualThroughput(3000);
entityTypeBuilder.HasAutoscaleThroughput(12000);
entityTypeBuilder.HasManualThroughput(5000);
entityTypeBuilder.HasAutoscaleThroughput(3000);
});
#endregion

Expand Down