Skip to content

EF Core for Cosmos is setting an Owned Entity Property with the same value as the Key #31903

@dotnetcadet

Description

@dotnetcadet

Issue

Ran into an issue where when I save a user entity with or without setting User.Created.UserId it is overriding the User ID in the owned entity with the Key of the parent that owns it. This only occurs when the property name is the same.

Models

public enum UserType
{
    Internal,
    External
}
public enum EntityType
{
    User
}
public sealed class AuditField
{
    public string? UserId { get; set; }
    public DateTime? Timestamp { get; set; }
    public bool? IsSystem { get; set; }
}
public abstract class Entity
{
    public virtual string? Id { get; set; }
    public EntityType EntityType { get; set; }
    public AuditField? Created { get; set; }
    public AuditField? Updated { get; set; }
    public IDictionary<string, string> Meta { get; set; } = new Dictionary<string, string>();
}
public class User : Entity {
    public override string? Id 
    { 
        get => UserId; 
        set => UserId = value; 
    }
    public string? UserId { get; set; }
    public string? Username { get; set; }
    public bool? IsEnabled { get; set; }
    public UserType? UserType { get; set; }
    public PersonDetails? Details { get; set; }
}

EF Core DB Context

public class SomeDbContext : DbContext 
{
        protected override void OnModelCreating(ModelBuilder builder)
        {
                 builder.Entity<User>(entity =>
                {
                           entity.ToContainer(UsersContainer);
                           entity.HasDiscriminator(p => p.EntityType).HasValue(EntityType.User).IsComplete();
                           entity.HasPartitionKey(p => p.UserId);
                           entity.HasKey(p => p.UserId);

                           entity.Property(p => p.Id).ToJsonProperty("id");
                           entity.Property(p => p.UserId).ToJsonProperty("userId");
                           entity.Property(p => p.EntityType).ToJsonProperty("entityType");
                           entity.Property(p => p.UserType).ToJsonProperty("userType");
                           entity.Property(p => p.Username).ToJsonProperty("username");
                           entity.Property(p => p.IsEnabled).ToJsonProperty("isEnabled");
                           entity.Property(p => p.Meta).ToJsonProperty("meta");

                           entity.OwnsOne(p => p.Details, details =>
                           {
                               details.ToJsonProperty("details");
                               details.Property(p => p.FirstName).ToJsonProperty("firstName");
                               details.Property(p => p.LastName).ToJsonProperty("lastName");
                               details.Property(p => p.MiddleName).ToJsonProperty("middleName");
                           });
                           entity.OwnsOne(p => p.Created, created =>
                           {
                               created.ToJsonProperty("created");
                               created.Property(p => p.IsSystem).ToJsonProperty("isSystem");
                               created.Property(p => p.UserId).ToJsonProperty("userId");
                               created.Property(p => p.Timestamp).ToJsonProperty("timestamp");
                           });
                           entity.OwnsOne(p => p.Updated, updated =>
                           {
                               updated.ToJsonProperty("updated");
                               updated.Property(p => p.IsSystem).ToJsonProperty("isSystem");
                               updated.Property(p => p.UserId).ToJsonProperty("userId");
                               updated.Property(p => p.Timestamp).ToJsonProperty("timestamp");
                           });
                       });
        }
}

Out Come

You can see that the userId in the created object is being set even though I am setting it with a different Id.

dbContext.Users.Add(new User()
{
    UserId = Guid.NewGuid().ToString(),
    Username = "test@username.com",
    IsEnabled = true,
    Details = new()
    {
        FirstName = "Chase",
        LastName = "Test"
    },
    Created = new()
    {
        IsSystem = false,
        Timestamp = DateTime.UtcNow,
        UserId = Guid.NewGuid().ToString()
    }
});
dbContext.SaveChanges();
image

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions