I am trying to model the following self-referencing person class in EF6.
public class Person
{
public int ID { get; set; }
public string Name { get; set; }
public int? MotherId { get; set; }
public Person Mother { get; set; }
public int? FatherId { get; set; }
public Person Father { get; set; }
public virtual ICollection<Person> Children { get; set; }
}
And my DbContext looks like this:
public virtual DbSet<Person> People { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Person>()
.HasOptional(m => m.Mother)
.WithMany(c => c.Children)
.HasForeignKey(m => m.MotherId);
modelBuilder.Entity<Person>()
.HasOptional(f => f.Father)
.WithMany(c => c.Children)
.HasForeignKey(f => f.FatherId);
}
When trying to add a person to the database using the following code:
db.People.Add(new Person { Name = "Jane Doe" });
I get this error:
An unhandled exception of type 'System.InvalidOperationException' occurred in EntityFramework.dll
Additional information: Sequence contains no matching element
What does this error mean, and how do I correct it? Optionally, is there a better way to model this object (ex: using subclass of Mother:Person and Father:Person)?
I have come up with the following solution that generates a clean database and allows for greater flexibility when adding relationships:
public interface IParent
{
ICollection<Person> Children { get; set; }
}
public class Person
{
public int ID { get; set; }
public string Name { get; set; }
public int? MotherId { get; set; }
public Female Mother { get; set; }
public int? FatherId { get; set; }
public Male Father { get; set; }
}
public class Male : Person, IParent
{
public virtual ICollection<Person> Children { get; set; }
}
public class Female : Person, IParent
{
public virtual ICollection<Person> Children { get; set; }
}
The DbContext only contains:
public virtual DbSet<Person> People { get; set; }
public virtual DbSet<Female> Females { get; set; }
public virtual DbSet<Male> Males { get; set; }
And the resulting database looks like this:
ID Name MotherId FatherId Discriminator
1 Jane NULL NULL Female
2 John NULL NULL Male
3 Jimmy 1 2 Male
4 Jenn 1 2 Female
This solution also gives the flexibility of adding relationships in multiple ways:
mom.Children.Add(son); // or
son.Mother = mom;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With