Conventions in Entity Framework Core are the default rules by which the Database Schema is created based on Domain and Database Context classes.
Let us consider the below domain and db context classes to understand how conventions work in EF Core.
public class Employee
{
public int Id { get; set; }
public int DepartmentId { get; set; }
public string Name { get; set; }
public string Designation { get; set; }
public Department Department { get; set; }
}
public class Department
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<Employee> Employee { get; set; }
}
public class CompanyContext : DbContext
{
public DbSet<Employee> Employee { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
optionsBuilder.UseSqlServer(@"Server=vaio;Database=Company;Trusted_Connection=True;");
}
}
}
The Entity Framework Core will create database table, with the same name as the property, for all DbSet properties given in the context class.
It will also create tables for the domain class that are not included as DbSet properties but are reachable through Reference Navigation Properties in other domain class.
Here in this case 2 database tables are created which are Employee and Department in the SQL Server database. The reason why these 2 tables are created is because the Employee class is included in the database context class’s (i.e. CompanyContext.cs) DbSet property while the Department class is reachable through a Reference Navigation Property – public Department Department { get; set; }.
EF Core creates columns in the database table for all the scalar properties in the domain classes. The column names are kept the same as the property name. The Employee class has 4 scalar properties (Id, DepartmentId, Name, Designation) so 4 columns with the same name will be created in the Employee table.
Similarly 2 columns with the name Id & Name will be created in the Department table.
Reference and collection properties are used to create relationships between the tables.
The mappings of data types between C# and SQL Server are given below:
C# Data Type | Mapping to SQL Server Data Type |
---|---|
int | int |
string | nvarchar(Max) |
decimal | decimal(18,2) |
float | real |
bool | bit |
long | bigint() |
datetime | datetime |
short | smallint |
Null columns are created for all reference data types and nullable primitive type properties like string, Nullable, float?.
Entity Framework Core will create NotNull columns in the database tables for primary key properties and primitive type properties like float, int, DateTime.
The EF Core creates the primary key for a database table for the property which is named Id (case insensitive).
For the Employee table the EF Core will create primary key if the Employee domain class includes a property named id, ID, iD, Id, employeeid, EmployeeId, EMPLOYEEID, EmPLoyEEid, etc.
The Entity Framework Core will create foreign key column for each reference navigation property in the domain class.
Here in this case (for ‘Employee’ & ‘Department’ domain classes) it will create foreign key column called DepartmentId in the Employee table.
Here you will learn how to apply One-to-Many Relationship between domain classes in Entity Framework Core.
Suppose you want to create 2 database tables – Country & City. You want to have One-to-Many relationship between them so that many cities are associated with one country.
These are the 2 Classes – Country & City, with the following properties.
public class Country
{
public int Id { get; set; }
public string Name { get; set; }
}
public class City
{
public int Id { get; set; }
public string Name { get; set; }
}
There are 4 conventions to create a Many-to-One relationship between these 2 classes. These conventions are:
On the City class create a reference navigation property pointing to the Country class as shown below:
public class City
{
public int Id { get; set; }
public string Name { get; set; }
public Country Country { get; set; } //Reference Navigation Property
}
public class Country
{
public int Id { get; set; }
public string Name { get; set; }
}
On applying the EF Core Migrations it will produce a one-to-many relationship (foreign key) between the City and Country tables in the database, where City table includes a nullable foreign key called ‘CountryId’, as shown by the image given below.
Another way to create one-to-many relationship is by adding Collection Navigation Property i.e. by ICollection type in the Country class as shown below.
public class City
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Country
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<City> Cities { get; set; } // Collection Navigation Property
}
This will do the same work as the Convention 1.
You can also create both Reference & Collection Navigation Properties on the entities to create foreign key relationship (One-to-Many).
public class City
{
public int Id { get; set; }
public string Name { get; set; }
public Country Country { get; set; } //Reference Navigation Property
}
public class Country
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<City> Cities { get; set; } // Collection Navigation Property
}
One the above code you can see that I have added Reference Navigation Property on the City entity, and Collection Navigation Property on the Country entity.
Here you use the Convention 3 and also adds a foreign key property CountryId of type int on the City entity.
public class City
{
public int Id { get; set; }
public string Name { get; set; }
public int CountryId { get; set; } //Foreign Key entity
public Country Country { get; set; } //Reference Navigation Property
}
public class Country
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<City> Cities { get; set; } // Collection Navigation Property
}
Creating One-to-One relationship between entity classes is very simple in EF Core. All you have to do is add Reference Navigation properties on both the entities.
In the below code I have created One-to-One Relationship between the ‘Country’ & ‘City’ entity classes.
public class City
{
public int Id { get; set; }
public string Name { get; set; }
public Country Country { get; set; } //Reference Navigation Property
}
public class Country
{
public int Id { get; set; }
public string Name { get; set; }
public City City { get; set; } //Reference Navigation Property
}
I have shown this on the below image:
To establish Many-to-Many Relationship between entities you have to use Fluent APIs. I have covered this in details at my tutorial called Configure Many-to-Many relationship using Fluent API in Entity Framework Core
Download the source codes: