[entity framework core] Entity Framework Core One To Many Relationships
link: https://www.learnentityframeworkcore.com/conventions/one-to-many-relationship
this artical mainly talking about how to define an one to many relationship in your project.
By Conventions
- case 1
public class Author
{
public int AuthorId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public ICollection<Book> Books { get; set; }
}
public class Book
{
public int BookId { get; set; }
public string Title { get; set; }
}
we don't defind the author id in book table. so the Ef core will auto generate a shadow property: author id, and the type is nullable,
CREATE TABLE [Books] (
[BookId] int NOT NULL IDENTITY,
[AuthorId] int,
[Title] nvarchar(max),
CONSTRAINT [PK_Books] PRIMARY KEY ([BookId]),
CONSTRAINT [FK_Books_Authors_AuthorId] FOREIGN KEY ([AuthorId])
REFERENCES [Authors] ([AuthorId]) ON DELETE NO ACTION
);
- case 2 Inverse Navigation Property
public class Author
{
public int AuthorId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public ICollection<Book> Books { get; set; }
}
public class Book
{
public int BookId { get; set; }
public string Title { get; set; }
public Author Author { get; set; }
}
- case 3 Fully Defined Relationship
the relationship is a required relationship. That means that a dependant cannot exist without its principal. If an author is deleted, all of the authors books must also be deleted.
public class Author
{
public int AuthorId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public ICollection<Book> Books { get; set; }
}
public class Book
{
public int BookId { get; set; }
public string Title { get; set; }
public int AuthorId { get; set; }
public Author Author { get; set; }
}
- case 4 Optional Relationships
public class Property
{
public int PropertyId { get; set; }
public string Address { get; set; }
public List<Tenant> Tenants { get; set; }
}
public class Tenant
{
public int TenantId { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public int? PropertyId { get; set; }
public Property Property { get; set; }
}
By fluent API
Most one-to-many relationships in an Entity Framework Core model follow conventions and require no additional configuration. Where the model does not follow convention, the Fluent API can be used to configure the correct relationship between entities.
inverse navigation prop mode
public class Company
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<Employee> Employees { get; set; }
}
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
public Company Company { get; set; }
}
for fluent api:
protected override void OnModelCreating(Modelbuilder modelBuilder)
{
modelBuilder.Entity<Company>()
.HasMany(c => c.Employees)
.WithOne(e => e.Company);
}
protected override void OnModelCreating(Modelbuilder modelBuilder)
{
modelBuilder.Entity<Company>()
.HasMany(c => c.Employees)
.WithOne(e => e.Company).
.IsRequired();
}
protected override void OnModelCreating(Modelbuilder modelBuilder)
{
modelBuilder.Entity<Company>()
.HasMany(c => c.Employees)
.WithOne(e => e.Company).
.OnDelete(DeleteBehavior.SetNull);
}
protected override void OnModelCreating(Modelbuilder modelBuilder)
{
modelBuilder.Entity<Company>()
.HasMany(c => c.Employees)
.WithOne(e => e.Company).
.OnDelete(DeleteBehavior.Delete);
}