My app has an abstract base/parent class (Contact), and concrete child classes (Phone, Email) inheriting from the base, and other classes referenced from the base - I left Person and Notes for the sake of the question.
public class Phone : Contact
{
public ConnectionType Type { get; set; } //public enum ConnectionType { Landline, Mobile, Fax, }
//phone-specific fields
}
public class Email : Contact
{
//email-specific fields
}
public abstract class Contact
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
//possibly something like public string Type { get; private set; } to be set with this.GetType().Name or enum based on similar logic
public string Value { get; set; }
// shared properties
public UsageType Type { get; set; } //public enum UsageType { Personal, Business, Other, }
public int PersonId { get; set; }
[ForeignKey(nameof(PersonId))]
public Person Person { get; set; }
public List<Note> Notes { get; set; }
// ... other shared properties
}
public class Note
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public int ContactId { get; set; }
public string Header { get; set; }
public string Content { get; set; }
[ForeignKey(nameof(ContactId))]
public Contact Contact { get; set; }
}
This mimics domain logic.
Can I make EF Core create these tables:
- Contacts
- Phones (1-to-1 with Contact)
- Emails (1-to-1 with Contact)
- Persons (1-to-many with Contact)
- Notes (many-to-1 with Contact)
without breaking parent-child relationship and with having same Id in parent and child?
I understand I can create database 1-to-1 parent-child relationship like
public class Phone
{
[Key]
public int Id { get; set; }
public int ContactId { get; set; }
[ForeignKey(nameof(ContactId))]
public Contact Contact { get; set; }
}
public class Email
{
[Key]
public int Id { get; set; }
public int ContactId { get; set; }
[ForeignKey(nameof(ContactId))]
public Contact Contact { get; set; }
}
public class Contact
{
[Key]
public int Id { get; set; }
}
which ultimately is going to provide my app with the same data, but I have an existing app which uses a NoSQL Db as a storage and I am changing the app to use a SQL database backed by EF Core and didn't want to make changes to the code much until it is absolutely necessary, plus currently our API allows to attach notes to any contact by contact Id and this is not possible to change as we cannot demand from users to change their API calls.
Edit: seems to be a duplicate of
Entity Framework : Table per Concrete Type and unique IDs across tables
which I didn't find when I was researching, sorry.
Funny enough, they even have almost same names in one of the answers!
Contacttable, you could make yourNotetable a TPH, with a discriminator and separate foreign key columns to each parent type.... Either design will work though.