I have an entity that can include other entities of the same type.
The entity looks like this:
public class PublicHolidayCalendar
{
public Guid Id { get; set; }
public virtual ICollection<PublicHolidayCalendarInclusion> IncludedCalendars { get; set; } = new HashSet<PublicHolidayCalendarInclusion>();
}
public class PublicHolidayCalendarInclusion
{
public Guid IncludedInCalendarId { get; set; }
public Guid IncludedCalendarId { get; set; }
public virtual PublicHolidayCalendar IncludedInCalendar { get; set; }
public virtual PublicHolidayCalendar IncludedCalendar { get; set; }
}
In the OnConfiguring of my DB context, I configure the relationship as follows:
modelBuilder.Entity<PublicHolidayCalendarInclusion>()
.HasKey(x => new { x.IncludedCalendarId, x.IncludedInCalendarId });
modelBuilder.Entity<PublicHolidayCalendarInclusion>()
.HasOne(x => x.IncludedCalendar)
.WithMany(x => x.IncludedCalendars)
.HasForeignKey(x => x.IncludedCalendarId)
.OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity<PublicHolidayCalendarInclusion>()
.ToTable("PublicHolidayCalendarInclusions");
If I now add an inclusion with this method:
public async Task AddIncludedCalendar(Guid id, Guid includedCalendarId)
{
var calendar = await context.PublicHolidayCalendars
.Include(x => x.IncludedCalendars)
.FirstOrDefaultAsync(f => f.Id == id)
.ConfigureAwait(false);
calendar.IncludedCalendars.Add(new PublicHolidayCalendarInclusion
{
IncludedCalendarId = includedCalendarId,
IncludedInCalendarId = id,
});
await context.SaveChangesAsync().ConfigureAwait(false);
}
Everything works out, but if I check the database, it now has an entry in the PublicHolidayCalendarInclusions table that has both IncludedInCalendarId and IncludedCalendarId properties set to the same value (the value of id in the AddIncludedCalendar method).
I've tried adding a second navigation property to PublicHolidayCalendar
public virtual ICollection<PublicHolidayCalendarInclusion> IncludedInCalendars { get; set; }
and configure the relationship as follows
modelBuilder.Entity<PublicHolidayCalendarInclusion>()
.HasOne(x => x.IncludedInCalendar)
.WithMany(x => x.IncludedInCalendars)
.HasForeignKey(x => x.IncludedInCalendarId)
.OnDelete(DeleteBehavior.Restrict);
but I get the same result. What am I missing?
If I refomulate the model like :
Then the navigation definition is :
So, a child has children... Make more sense if parent has children, like :
What
IncludedInCalendarIdandIncludedCalendarIdhas the value of the root id? The relation definition is :So when something is added
IncludedCalendars, on SaveChange the relation properties (IncludedCalendarandIncludedCalendarId) are overrided with the calendar :