Default Conventions in Entity Framework Core

Default Conventions in Entity Framework Core (EF Core)

In this article, I am going to discuss Default Conventions in Entity Framework Core (EF Core) with Examples. Please read our previous article, where we discussed Explicit Loading in Entity Framework (EF) Core with Examples.

Default Conventions in EF Core 

When using Entity Framework Core, conventions refer to a collection of default rules that are automatically set up based on the model classes. In previous articles, we demonstrated examples of using Entity Framework Core and observed that the EF Core automatically configured primary keys, foreign keys, indexers, relationships between tables, and appropriate data types for columns from the domain classes without requiring any extra configurations.

The Entity Framework Core Default Conventions make it possible to automatically configure the database schema based on conventions set by the EF Core API. It’s also possible to modify these default conventions, which we’ll cover in future articles. Let’s concentrate on understanding the Entity Framework Core Default Conventions.

Note: I assume you have installed the required EF Core Packages. If not, then please check the following article, where I discussed How to Install Entity Framework Core.

Creating the Models:

Let us understand the Default Naming Conventions, which are followed by Entity Framework Core. So, first of all, create the following Entities. So, a new Console Application and then create a folder with the name Entities, and within that folder, create the following classes.

Students.cs

Create a new class file with the name Students.cs and then copy and paste the following code into it.

namespace EFCoreCodeFirstDemo.Entities
{
    public class Student
    {
        public int StudentId { get; set; }
        public string? FirstName { get; set; }
        public string? LastName { get; set; }
        public DateTime? DOB { get; set; }
        public byte[]? Photo { get; set; }
        public decimal? Height { get; set; }
        public float? Weight { get; set; }
        public bool IsPassout { get; set; }
        public virtual Standard? Standard { get; set; }
        public int GradeId { get; set; }
        public Grade? Grade { get; set; }
    }
}
Standard.cs

Next, create a new class file with the name Standard.cs and then copy and paste the following code into it.

namespace EFCoreCodeFirstDemo.Entities
{
    public class Standard
    {
        public int Id { get; set; }
        public string? StandardName { get; set; }
        public string? Description { get; set; }
        public virtual IList<Student>? Students { get; set; }
    }
}
Grade.cs

Create a new class file with the name Grade.cs and then copy and paste the following code into it.

using System.ComponentModel.DataAnnotations;
namespace EFCoreCodeFirstDemo.Entities
{
    public class Grade
    {
        public int GradeId { get; set; }
        public string? GradeName { get; set; }
        public string? Section { get; set; }
        public virtual IList<Student>? Students { get; set; }
    }
}
Creating the Context Class:

Next, create a class file with the name EFCoreDbContext.cs and then copy and paste the following code into it. Here, we have the Student and Standard as the DbSet Properties but have not added the Grade Entity as a DbSet Property.

using Microsoft.EntityFrameworkCore;
namespace EFCoreCodeFirstDemo.Entities
{
    public class EFCoreDbContext : DbContext
    {
        //Constructor calling the Base DbContext Class Constructor
        public EFCoreDbContext() : base()
        {
        }

        //OnConfiguring() method is used to select and configure the data source
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            //Configuring the Connection String
            optionsBuilder.UseSqlServer(@"Server=LAPTOP-6P5NK25R\SQLSERVER2022DEV;Database=EFCoreDB;Trusted_Connection=True;TrustServerCertificate=True;");
        }

        //OnModelCreating() method is used to configure the model using ModelBuilder Fluent API
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            //Use this to configure the model using Fluent API
        }

        //Adding Domain Classes as DbSet Properties
        //In The database it will create the table with the name Students
        public DbSet<Student> Students { get; set; }

        //In The database it will create the table with the name Standard
        public DbSet<Standard> Standard { get; set; }
    }
}

Note: As we already discussed, whenever we add or update domain classes or configurations, we need to sync the database with the model using add-migration and update-database commands using Package Manager Console or .NET Core CLI. Open the Package Manager Console, and then execute the add-migration CreateEFCoreDB1 command as follows:

Default Conventions in Entity Framework Core (EF Core) with Examples

Again, in the Package Manager Console and execute the Update-Database command as follows:

Default Conventions in Entity Framework Core (EF Core) with Examples

Once the Update-Database command is executed successfully, it will update the database with these two tables.

What are the Default Entity Framework Core Conventions?

Let us understand the Default Entity Framework Core Conventions. They are as follows:

Schema:

By default, the Entity Framework Core API creates all the database objects with the dbo schema. If you verify the database tables, then you will see that the database tables are created with the dbo schema, as shown in the below image.

Schema

Table Name:

The EF Core API creates database tables for all properties defined in the context class as DbSet<TEntity> with the same name as the property name. It can also create tables for entities that aren’t listed as DbSet properties but are still reachable through reference properties in other DbSet entities. In our example, EF Core will create the Students table for the DbSet<Student> property which is there in the EFCoreDbContext class, and the Grade table for the Grade property, which we defined inside the Student entity class, despite the EFCoreDbContext class not featuring the DbSet<Grade> property. Similarly, for the DbSet<Standard> Standard property, EF Core will create the Standard table in the database. The diagram below may provide a better understanding.

Table Name

Primary Key Name:

When using EF Core, a primary key column will be automatically generated for a property named “Id” or “<Entity Class Name> + Id” (regardless of capitalization). For instance, if the Student class has a property named id, ID, iD, Id, studentid, StudentId, STUDENTID, or sTUdentID, EF Core will create a Primary Key column in the Students table.

For our example, we added the properties StudentId, GradeId, and Id to the respective model classes for Student, Grade, and Standard. As a result, these three properties will serve as the Primary Key columns in the corresponding database tables, as illustrated in the image below.

Primary Key Name

Note: If both Id and <Entity Class Name> + Id properties are present in a single model class, then it will create the Primary key based on the Id column only. If the model class does not have any key property, then Entity Framework will throw an exception.

Foreign Key Column Name:

EF Core API will create a foreign key column for each reference navigation property in an entity with one of the following naming patterns per the foreign key convention.

  1. <Reference Navigation Property Name>Id
  2. <Reference Navigation Property Name><Principal Primary Key Property Name>

In our example (Student, Grade, and Standard entities), EF Core will create foreign key columns GradeId, and StudentId in the Students table, as shown in the below image.

Foreign Key Column Name

Here, you can see, in the Student Entity, we have GradeId Property which will become the Foreign Key for the Grade table. But we don’t add any Foreign Key Property for Student Reference Property. So, in the case of the Student Reference Property, it will add (Standard + Id) as a Reference Property. This is because the Standard Entity has Id as the primary key. For a better understanding, please have a look at the Student table.

Foreign Key Column Name

The following table lists foreign key column names for different reference property names and primary key property names.

Null and Not Null Columns:

By default, the Entity Framework Core API will create a null column for all reference type properties and nullable primitive properties, for example, string, Nullable<int>, Student, and Standard (all class type properties). And the Entity Framework Core will create Not Null columns for Primary Key properties and non-nullable value type properties, for example, int, bool, etc. For a better understanding, please look at the image below, which shows Student Entity and the corresponding Students database table.

Default Conventions in EF Core with Examples

DB Columns Order:

The Entity Framework Core will create the Database table columns in the same order as the properties are added in the entity class. However, the primary key columns would be moved to the first position in the table.

Column Data Type

The data type for columns in the database table depends on how the provider for the database has mapped the C# data type to the data type of a selected database. The following table lists mapping between the C# data type and to SQL Server column data type.

Default Conventions in Entity Framework (EF) Core with Examples

Index

EF Core creates a clustered index on Primary key columns and a non-clustered index on Foreign Key columns by default.

In the next article, I am going to discuss Data Annotation Attributes in Entity Framework Core with Examples. In this article, I try to explain Default Conventions in Entity Framework (EF) Core with Examples, and I hope you enjoyed this Default Conventions in EF Core with Examples article. Please give your valuable feedback and suggestions about this article.

Leave a Reply

Your email address will not be published. Required fields are marked *