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 [];
}