dotnet / dotnet/efcore

Cosmos: Changed non-persisted property on embedded entity type updates document on SaveChanges

Open
#37,929 8 comments 0 reactions 1 assignee Claimed by @AndriySvyryd View on GitHub
area-cosmos customer-reported
Dominant language
C#
Stars
14.8k
Forks
3.4k
PR merge metrics
PR metrics pending

Description

### Bug description

As per `Can_use_non_persisted_properties`, non persisted property changes should not cause document updates on SaveChanges

Can_use_non_persisted_properties

```csharp
public async Task Can_use_non_persisted_properties(bool transactionalBatch)
{
var contextFactory = await InitializeNonSharedTest(
shouldLogCategory: _ => true,
onConfiguring: o => o.ConfigureWarnings(w => w.Log(CosmosEventId.NoPartitionKeyDefined)));

var customer = new Customer { Id = 42, Name = "Theon" };

using (var context = CreateContext(contextFactory, transactionalBatch))
{
await context.AddAsync(customer);

await context.SaveChangesAsync();
Assert.Equal("Theon", customer.Name);
}

using (var context = CreateContext(contextFactory, transactionalBatch))
{
var customerFromStore = await context.Set().SingleAsync();

Assert.Equal(42, customerFromStore.Id);
Assert.Null(customerFromStore.Name);

customerFromStore.Name = "Theon Greyjoy";

Assert.Equal(0, await context.SaveChangesAsync());
}
}

private class UnmappedCustomerContext(DbContextOptions dbContextOptions) : DbContext(dbContextOptions)
{
protected override void OnModelCreating(ModelBuilder modelBuilder)
=> modelBuilder.Entity().Property(c => c.Name).ToJsonProperty("");
}
```

But for non-persisted scalar properties on owned (and complex) embedded types, SaveChanges does update the document.

### Your code

```csharp
[ConditionalFact]
public virtual async Task Can_use_non_persisted_properties_owned()
{
var options = await Fixture.CreateOptions(
modelBuilder =>
{
modelBuilder.Entity(eb => eb.OwnsOne(
v => v.Operator, b =>
{
b.Property(x => x.Name).ToJsonProperty("");
}));
},
seed: false);

using (var context = new EmbeddedTransportationContext(options))
{
var vehicle = new Vehicle
{
Name = "Test Vehicle",
Operator = new Operator { Name = "Test Operator" }
};
await context.AddAsync(vehicle);
await context.SaveChangesAsync();

Assert.Equal("Test Operator", vehicle.Operator.Name);
}

using (var context = new EmbeddedTransportationContext(options))
{
var vehicle = await context.Vehicles.SingleAsync();
Assert.Null(vehicle.Operator.Name);

vehicle.Operator.Name = "Theon Greyjoy";
Assert.Equal(0, await context.SaveChangesAsync()); // Fails: Actual: 1
}

using (var context = new EmbeddedTransportationContext(options))
{
var vehicle = await context.Vehicles.SingleAsync();
Assert.Null(vehicle.Operator.Name);
}
}
```

### EF Core version

10.0 & main

### Database provider

Microsoft.EntityFrameworkCore.Cosmos

### Target framework

.NET 10

### Operating system

W11

### IDE

VS 2026

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.