79254493

Date: 2024-12-05 11:37:08
Score: 0.5
Natty:
Report link

An addition for a collection of owned properties:

// Parent entity
public class Person
{
    public Guid Id { get; set; }
    public string Name { get; set; }

    public ICollection<Address> Addresses { get; set; }
}

// Owned Type
public class Address {
    public string Street { get; set; }
    public string Number { get; set; }
}

...

// Configuration
public class PersonConfiguration : IEntityTypeConfiguration<Person>
{
    public void Configure(EntityTypeBuilder<Person> builder)
    {
        builder.OwnsMany(person => person.Addresses);
    }
}

...

// On Address (owned property) modified:
var modifiedEntities = _dbContext.ChangeTracker.Entries<Person>()
    .Where(x => x.State == EntityState.Modified)
    .Select(p => p.Entity);
modifiedEntities = modifiedEntities.Concat(GetParentEntitiesOfModifiedOwnedEntities(modifiedEntities.Select(e => e.Id)));

The method for retrieving the parent/owner entities:

/// <summary>
/// Retrieve parent/owner entities of the modified Address entities.
/// </summary>
/// <param name="addedAndModifiedEntityIds">Ids of added and modified entities</param>
private IEnumerable<Person> GetParentEntitiesOfModifiedOwnedEntities(IEnumerable<Guid> addedAndModifiedEntityIds)
{
    var modifiedAddressEntities = _dbContext.ChangeTracker.Entries<Address>()
        .Where(p => p.State == EntityState.Modified || p.State == EntityState.Added || p.State == EntityState.Deleted);
    /* An owned entity (Address) has two shadow properties:
     * - Id: the internal unique id of the owned entity (here an int)
     * - 'external id': the id of the parent/owned entity (here a Guid)
     * 
     * To retrieve the second one, we search for the shadow property which doesn't have the name "Id"
     */
    var linkedMemberIds = modifiedAddressEntities 
        .Select(e => Guid.Parse(e.Members.First(m => m.Metadata.IsShadowProperty() && m.Metadata.Name != "Id").CurrentValue.ToString()))//get the parent entity id
        .Except(addedAndModifiedEntityIds)
        .ToHashSet();
    if (linkedMemberIds.Any())
        return _dbContext.ChangeTracker.Entries<Person>()
            .Where(e => linkedMemberIds.Contains(e.Entity.Id))
            .Select(p => p.Entity);

    return [];
}

Source: https://learn.microsoft.com/en-us/answers/questions/2125302/efcore-owned-property-state-for-parent-entity?page=1&orderby=helpful#answers

Reasons:
  • Probably link only (1):
  • Long answer (-1):
  • Has code block (-0.5):
  • Low reputation (1):
Posted by: ArnaudB