I'm building an Asp.Net core Api project. I have a Parent entity as Aggregate root. That parent entity has a collection of Owned types. If instead of collection of Owned types I have collection of Entities, I would simply tell the parent to delete the entity by it's Id like this:
// Parent entity method
public void DeleteChild(int childId)
{
var existing = this._children.FirstOrDefault(x=>x.Id == childId);
...
this._children.Remove(existing);
}
How to delete the owned object in the collection of an aggregate (owned entity does not have an Id property)?
//Parent entity method
public void DeleteChild(?????????) //Don't know what to put here, a surrogate key?
{
...
}
The model is something like this:
public class Parent
{
public int Id {get;set;}
public string Name {get;set;}
public List<Child> Children {get;set;}
... //other non important props
}
public class Child
{
public string Name {get;set;}
... //other non important props
}
And the mapping:
public class ParentEntityConfiguration : IEntityTypeConfiguration<Parent>
{
public void Configure(EntityTypeBuilder<Device> builder)
{
builder.ToTable("Parents");
builder.HasKey(x => x.Id);
builder.OwnsMany<Child>("Children", cfg =>
{
cfg.ToTable("Children");
cfg.WithOwner().HasForeignKey("ParentId");
cfg.HasKey("ParentId", "Name");
cfg.HasIndex("ParentId", "Name").IsUnique();
});
}
}
So there is no "Id" propety in the Child nor the "ParentId" as they are shadowed.
The same goes for modifying the Owned object. What is the best practice for this?
Thanks
P.S. I'm using EF Core 6.x
Edit: Given the added details in the question.
You are using a composite key for your child which is a combination between the child's name and the parentid. Since child is a owned type it will be automatically included when you retrieve the object of the parent. (If you didn't change the configuration AutoInclude
)
So if you get your parent object like:
var parent = dbcontext.Parent.Where(p => p.id = idParent);
//find the one you want to eliminate by name.
var child = parent.children.First(item => item.name == "foo").value;
//remove the child from the list
parent.children.Remove(child);
//save changes
dbcontext.SaveChangesAsync();
================================================================ OLD:
You just have to find the parent first. Then you can iterate through the childrens and delete the ones that you want. Then just call the save changes and they should be removed.
Example:
// Parent entity method
public void DeleteChild(int childId, idParent)
{
var parent= dbcontext.Parent.FirstOrDefault(x=>x.Id == idparent);
for (int i = 0; i < parent.Children.length; i++)
{
if (collection[i].id = childId)
collection[i] = null;
}
dbcontext.SaveChangesAsync();
}