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
10 changes: 5 additions & 5 deletions entity-framework/core/providers/cosmos/unstructured-data.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ EF Core was designed to make it easy to work with data that follows a schema def

## Accessing the raw JSON

It is possible to access the properties that are not tracked by EF Core through a special property in [shadow-state](xref:core/modeling/shadow-properties) named `"__jObject"` that contains a `JObject` representing the data received from the store and data that will be stored:
> [!NOTE]
> The `"__jObject"` shadow property was removed in EF Core 11. See [Breaking changes in EF Core 11](xref:core/what-is-new/ef-core-11.0/breaking-changes#cosmos-jObject-removed) for details.

In EF Core 10 and earlier, it was possible to access properties not tracked by EF Core through a special property in [shadow-state](xref:core/modeling/shadow-properties) named `"__jObject"` that contained a `JObject` representing the data received from the store and data that will be stored:

[!code-csharp[Unmapped](../../../../samples/core/Cosmos/UnstructuredData/Sample.cs?highlight=21,22&name=Unmapped)]

Expand All @@ -35,10 +38,7 @@ It is possible to access the properties that are not tracked by EF Core through
```

> [!WARNING]
> The `"__jObject"` property is part of the EF Core infrastructure and should only be used as a last resort as it is likely to have different behavior in future releases.

> [!NOTE]
> Changes to the entity will override the values stored in `"__jObject"` during `SaveChanges`.
> The `"__jObject"` property was part of the EF Core infrastructure and has been removed in EF Core 11. It should not be used in any version of EF Core as it is no longer available.

## Using CosmosClient

Expand Down
99 changes: 99 additions & 0 deletions entity-framework/core/what-is-new/ef-core-11.0/breaking-changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ This page documents API and behavior changes that have the potential to break ex

| **Breaking change** | **Impact** |
|:--------------------------------------------------------------------------------------------------------------- | -----------|
| [Cosmos: `__jObject` shadow property removed; JObject no longer used for serialization](#cosmos-jObject-removed) | High |
| [Cosmos: Unmapped properties are no longer preserved](#cosmos-unmapped-properties) | High |
| [Sync I/O via the Azure Cosmos DB provider has been fully removed](#cosmos-nosync) | Medium |
| [Microsoft.Data.SqlClient has been updated to 7.0](#sqlclient-7) | Medium |
| [Cosmos: illegal `id` characters are no longer escaped](#cosmos-no-id-escape) | Medium |
Expand All @@ -31,9 +33,78 @@ This page documents API and behavior changes that have the potential to break ex
| [SqlVector properties are no longer loaded by default](#sqlvector-not-auto-loaded) | Low |
| [Cosmos: empty owned collections now return an empty collection instead of null](#cosmos-empty-collections) | Low |
| [Cosmos: the default discriminator property is now named `Discriminator` in the model](#cosmos-discriminator-property-name) | Low |
| [Cosmos: floating-point values are now truncated when materializing to fixed-point types](#cosmos-truncation) | Low |
| [Owned JSON collections without an explicit key are obsolete](#owned-json-collections-obsolete) | Low |
| [`Property` no longer configures primitive collections](#property-not-primitive-collection) | Low |

## High-impact changes

<a name="cosmos-jObject-removed"></a>

### Cosmos: `__jObject` shadow property removed; JObject no longer used for serialization

[Tracking Issue #5421](https://github.com/dotnet/EntityFramework.Docs/issues/5421)

#### Old behavior

Previously, the Azure Cosmos DB provider added a shadow property named `"__jObject"` of type `JObject` (from `Newtonsoft.Json`) to every entity type. This property contained the raw JSON document as received from and sent to Cosmos DB, allowing access to unmapped or raw data:

```csharp
var order = await context.Orders.FirstAsync();
var rawJson = context.Entry(order).Property<JObject>("__jObject").CurrentValue;
var billingAddress = rawJson["BillingAddress"]?.Value<string>();
```

EF Core used `Newtonsoft.Json` (via `JObject`) internally for all document serialization and deserialization.

#### New behavior

Starting with EF Core 11, the `__jObject` shadow property no longer exists. EF Core now uses `System.Text.Json` (`Utf8JsonReader`/`Utf8JsonWriter`) for document serialization and deserialization, and no longer depends on `Newtonsoft.Json`.

Accessing the `"__jObject"` property will throw an `InvalidOperationException`.

#### Why

The `JObject`-based approach required a dependency on `Newtonsoft.Json` and limited performance improvements. Switching to `System.Text.Json` aligns EF Core Cosmos with the rest of the .NET ecosystem and enables significant performance gains in the materializer.

#### Mitigations

To access the raw JSON document, use the `CosmosClient` directly instead of relying on `__jObject`:

```csharp
var cosmosClient = context.Database.GetCosmosClient();
var container = cosmosClient.GetContainer("myDatabase", "myContainer");
var response = await container.ReadItemAsync<JsonElement>("1", new PartitionKey("1"));
var billingAddress = response.Resource.GetProperty("BillingAddress").GetString();
```

For more information, see [Working with Unstructured Data in Azure Cosmos DB](xref:core/providers/cosmos/unstructured-data).

<a name="cosmos-unmapped-properties"></a>

### Cosmos: Unmapped properties are no longer preserved

[Tracking Issue #5421](https://github.com/dotnet/EntityFramework.Docs/issues/5421)

#### Old behavior

Previously, when EF Core read a Cosmos DB document that contained JSON properties not mapped in the EF model, those extra properties were preserved in the `__jObject` shadow property and written back to the database on the next `SaveChanges`. Unmapped data in documents was transparently round-tripped.

#### New behavior

Starting with EF Core 11, unmapped JSON properties in a Cosmos DB document are ignored when reading. Any extra properties that are not part of the EF model will be lost if the entity is subsequently saved.

#### Why

Because `__jObject` has been removed (see above), there is no mechanism to preserve unmapped properties. EF Core 11 uses a lean JSON reader that only processes the properties it knows about from the model.

#### Mitigations

If your application relies on preserving unmapped data, consider one of the following options:

- **Use `CosmosClient` directly** for documents where you need full control over the JSON shape.
- **Map all relevant properties** explicitly in your EF model, including any extra fields that should be preserved.

## Medium-impact changes

<a name="cosmos-nosync"></a>
Expand Down Expand Up @@ -380,6 +451,34 @@ To restore the previous behavior where the discriminator property is also named
modelBuilder.Entity<Session>().HasDiscriminator<string>("$type");
```

<a name="cosmos-truncation"></a>

### Cosmos: Floating-point values are now truncated when materializing to fixed-point types

[Tracking Issue #38138](https://github.com/dotnet/efcore/issues/38138)

#### Old behavior

Previously, when a query projection returned a floating-point value (e.g., the result of a numeric expression such as `3 / 4` returned by Cosmos as `0.75`) and the target property was a fixed-point type (`int`, `long`, `decimal`, etc.), EF Core would **round** the value. For example, `0.75` would materialize as `1`.

#### New behavior

Starting with EF Core 11, such values are **truncated** instead of rounded. `0.75` now materializes as `0`, matching standard .NET integer truncation behavior (`(int)0.75 == 0`).

#### Why

Truncation is the standard .NET behavior for explicit numeric conversions and is consistent with how other providers behave. The previous rounding behavior was a bug.

#### Mitigations

If you relied on the previous rounding behavior, apply explicit rounding in your queries using `Math.Round`:

```csharp
var result = await context.Products
.Select(p => (int)Math.Round((double)(p.Int / (p.Int + 1))))
.SingleAsync();
```

<a name="owned-json-collections-obsolete"></a>

### Owned JSON collections without an explicit key are obsolete
Expand Down
13 changes: 13 additions & 0 deletions entity-framework/core/what-is-new/ef-core-11.0/whatsnew.md
Original file line number Diff line number Diff line change
Expand Up @@ -791,6 +791,19 @@ For more information, [see the documentation](xref:core/providers/cosmos/saving#

This feature was contributed by [@JoasE](https://github.com/JoasE) - many thanks!

<a name="cosmos-modernized-materializer"></a>

### Modernized JSON serializer

EF Core 11 modernizes the Azure Cosmos DB provider's document serialization and deserialization to use `System.Text.Json` (`Utf8JsonReader`/`Utf8JsonWriter`) internally, replacing the previous `Newtonsoft.Json`-based approach. This improves performance and removes the dependency on `Newtonsoft.Json`.

As part of this change, the `__jObject` shadow property (of type `JObject`) that was previously added to every entity type has been removed, and unmapped JSON properties in documents are no longer preserved on round-trip.

> [!IMPORTANT]
> These are breaking changes. See the [breaking changes documentation](xref:core/what-is-new/ef-core-11.0/breaking-changes#cosmos-jObject-removed) for details and mitigations.

This feature was contributed by [@JoasE](https://github.com/JoasE) - many thanks!

## Migrations

<a name="migrations-exclude-fk"></a>
Expand Down