Entity Configurations using Entity Framework Core Fluent API

Entity Configurations using Entity Framework (EF) Core Fluent API

In this article, I will discuss Entity Configurations using Entity Framework Core (EF Core) Fluent API with Examples. Please read our previous article discussing How to Configure Fluent API in Entity Framework Core with Examples. At the end of this article, you will understand the following pointers:

  1. Entity Configurations using Entity Framework Core Fluent API
  2. How to Configure Default Schema using Entity Framework Core Fluent API?
  3. How to Map Entity to Table using Fluent API in Entity Framework Core?
  4. Examples to Understand HasAlternateKey(), HasIndex(), HasKey(), and Ignore() Fluent API Methods.
  5. How to Create a Table without Primary Key using EF Core Fluent API?
Entity Configurations using Entity Framework Core Fluent API

Entity Framework Core’s Fluent API allows us to configure the mapping of our entity classes to database tables and define various aspects of their behavior. We can use the Fluent API to configure properties, relationships, keys, indexes, and more. Here, I am going to discuss how to use the Fluent API to configure entity classes in Entity Framework Core:

Example to Understand Entity Configurations using EF Core Fluent API:

We will use the following Student and Standard Entities to understand Entity Configurations in Entity Framework Core Code First Approach using Fluent API.

Student.cs
namespace EFCoreCodeFirstDemo.Entities
{
    public class Student
    {
        public int StudentId { get; set; }
        public string FirstName { get; set; }
        public string? LastName { get; set; }
        public string Branch { get; set; }
        public string City { get; set; }
        public string State { get; set; }
        public string Country { get; set; }
        public Standard Standard { get; set; }
    }
}
Standard.cs
namespace EFCoreCodeFirstDemo.Entities
{
    public class Standard
    {
        public int StandardId { get; set; }
        public string StandardName { get; set; }
        public string Description { get; set; }
        public ICollection<Student> Students { get; set; }
    }
}
Configure Default Schema using Entity Framework Core Fluent API Configuration:

Let us understand how to configure the default schema for the tables in the database. However, changing the schema while creating the individual tables is also possible. By default, the schema is created as dbo. For a better understanding, please modify the context class as follows.

using Microsoft.EntityFrameworkCore;
namespace EFCoreCodeFirstDemo.Entities
{
    public class EFCoreDbContext : DbContext
    {
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            //Configuring the Connection String
            optionsBuilder.UseSqlServer(@"Server=LAPTOP-6P5NK25R\SQLSERVER2022DEV;Database=EFCoreDB;Trusted_Connection=True;TrustServerCertificate=True;");
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
           
        }

        public DbSet<Student> Students { get; set; }
        public DbSet<Standard> Standards { get; set; }
    }
}

Note: Before Proceeding further, let us delete the EFCoreDB database using SSMS and Migration folder from our project.

With the above changes, open the Package Manager Console and Execute the add-migration and update-database commands as follows. You can give any name to your migration. Here, I am giving EFCoreDBMig1. The name that you are giving it should not be given earlier.

Configure Default Schema using Entity Framework Core Fluent API Configuration

Now, if you verify the database, you should see the following.

Configure Default Schema using Entity Framework Core Fluent API Configuration

Now, what our requirement is, instead of dbo, we want to set the default schema as Admin. To do so, we need to use the HasDefaultSchema method, and to this method, we need to pass the default schema name.

So, to configure a default schema for all tables in Entity Framework Core using the Fluent API, we need to use the ModelBuilder’s HasDefaultSchema method within the OnModelCreating method of our DbContext class. So, modify the Context class as follows. In the below code, we have set Admin as a default schema.

using Microsoft.EntityFrameworkCore;
namespace EFCoreCodeFirstDemo.Entities
{
    public class EFCoreDbContext : DbContext
    {
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            //Configuring the Connection String
            optionsBuilder.UseSqlServer(@"Server=LAPTOP-6P5NK25R\SQLSERVER2022DEV;Database=EFCoreDB;Trusted_Connection=True;TrustServerCertificate=True;");
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            // Set default schema
            modelBuilder.HasDefaultSchema("Admin");
        }

        public DbSet<Student> Students { get; set; }
        public DbSet<Standard> Standards { get; set; }
    }
}

With the above changes, open the Package Manager Console and Execute the add-migration and update-database commands as follows. You can give any name to your migration. Here, I am giving EFCoreDBMig2. The name that you are giving it should not be given earlier.

Entity Configurations using Entity Framework Core Fluent API

Now, if you verify the database, you should see the following. You will see that both the tables will be created with Admin schema, as shown in the below image.

Entity Configurations using Entity Framework Core Fluent API

By setting the default schema using HasDefaultSchema, every entity will be created under this schema unless specifically overridden using the ToTable method with the schema parameter. Later in this article, I will explain how to specify a different schema using the ToTable method.

Map Entity to Table using Fluent API in Entity Framework Core.

By default, the Entity Framework Core Code-First Approach will create the tables in the database with the name DbSet properties in the context class. For example, modify the context class as follows. Here, we have included two DbSet Properties named Students and Standards.

using Microsoft.EntityFrameworkCore;
namespace EFCoreCodeFirstDemo.Entities
{
    public class EFCoreDbContext : DbContext
    {
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            //Configuring the Connection String
            optionsBuilder.UseSqlServer(@"Server=LAPTOP-6P5NK25R\SQLSERVER2022DEV;Database=EFCoreDB;Trusted_Connection=True;TrustServerCertificate=True;");
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
           
        }

        public DbSet<Student> Students { get; set; }
        public DbSet<Standard> Standards { get; set; }
    }
}

In this case, the Entity Framework Core will create two tables in the database with the name Students and Standards as the DbSet Properties name are Students and Standards. We can override this default convention using Data Annotation Attribute and Fluent API in EF Core. We have already discussed using the Table Data Annotation Attribute with Entity Framework Core. Let us understand how to override the default convention using Entity Framework Core Fluent API.

How to Map Entity to Table using Fluent API in Entity Framework Core?

To Map an Entity to a Table using Entity Framework Fluent API, we must use the ToTable method. The ToTable() method is used to specify the name of the database table associated with the entity. Useful when the table name does not match the default naming convention

There are two overloaded versions available of this method. One overloaded version takes the tableName as a parameter, while the other method takes tableName and database schemaName as parameters.

So, modify the context class to give a table name different than the DbSet properties name. Here, we need to override the onModelCreating method. Even though the DbSet property names are Students and Standards, the Entity Framework Core will generate tables with the names StudentInfo and StandardInfo in the database. The point that you need to remember is that modelBuilder.Entity<TEntity>() returns the EntityTypeConfiguration object, using which we can configure many things.

using Microsoft.EntityFrameworkCore;
namespace EFCoreCodeFirstDemo.Entities
{
    public class EFCoreDbContext : DbContext
    {
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            //Configuring the Connection String
            optionsBuilder.UseSqlServer(@"Server=LAPTOP-6P5NK25R\SQLSERVER2022DEV;Database=EFCoreDB;Trusted_Connection=True;TrustServerCertificate=True;");
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            //Map Entity to Table
            modelBuilder.Entity<Student>().ToTable("StudentInfo"); //Default Schema will be dbo
            modelBuilder.Entity<Standard>().ToTable("StandardInfo", "Admin"); // Schema will be Admin
        }

        public DbSet<Student> Students { get; set; }
        public DbSet<Standard> Standards { get; set; }
    }
}

As you can see in the above code, we start with the Entity<TEntity>() method. Most of the time, we have to start with the Entity<TEntity>() method to configure the Entity using Fluent API, and here, we need to provide the Entity name for which we want to provide configuration. Then, we used the ToTable() method to map the Student entity to the StudentInfo table and the Standard entity to the StandardInfo table. Here, the StandardInfo table will be created with the Admin schema because we have specified the Admin schema for the StandardInfo table. Studentinfo table will be created with the default schema as we have not specified schema, and in this case, the default schema will be dbo.

With the above changes, open the Package Manager Console and Execute the add-migration and update-database commands as follows. You can give any name to your migration. Here, I am giving EFCoreDBMig3. The name that you are giving it should not be given earlier.

How to Map Entity to Table using Fluent API in Entity Framework Core?

Now, if you verify the database, you should see the following. Here, you can see the StudentInfo table is created with the default dbo schema, and the StandardInfo table is created with the Admin schema.

How to Map Entity to Table using Fluent API in Entity Framework Core?

HasAlternateKey(), HasIndex(), HasKey() and Ignore() Fluent API methods examples using EF Core

In Entity Framework Core, you can use various Fluent API methods to configure the database schema and entity mappings. Here are examples of how to use HasAlternateKey, HasIndex, HasKey, and Ignore methods in the Fluent API:

HasAlternateKey() Method:

The HasAlternateKey method is used to specify an alternate key for an entity. Alternate keys are unique constraints that allow us to enforce uniqueness on a set of columns other than the primary key.

modelBuilder.Entity<Employee>()
    .HasAlternateKey(p => p.Email); // Email is an alternate key
HasIndex() Method:

The HasIndex method creates an index on one or more columns of an entity to improve query performance.

modelBuilder.Entity<Employee>()
    .HasIndex(p => p.RegdNumber) // Create an index on the RegdNumber column
    .IsUnique(); // Make the index unique
HasKey() Method:

The HasKey method is used to specify the primary key of an entity. You can configure a composite key by passing multiple properties to the method.

Single-column primary key
modelBuilder.Entity<Employee>()
    .HasKey(p => p.EmpId); 

Composite key example
modelBuilder.Entity<Order>()
    .HasKey(o => new { o.EmpId, o.RegdNumber });
Ignore() Method:

The Ignore method excludes a property from being mapped to the database. This is useful when you have properties in your entity class that should not be persisted in the database. It also configures that the class should not be mapped to a table.

modelBuilder.Entity<Person>()
    .Ignore(p => p.TemporaryAddress); // Exclude TemporaryAddress property from mapping

Let us understand the above Fluent API Methods with an example.

Creating the Employee Model:

Create a class file named Employee.cs, then copy and paste the following code.

namespace EFCoreCodeFirstDemo.Entities
{
    public class Employee
    {
        public int EmpId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Email { get; set; }
        public string RegdNumber { get; set; }
        public string TemporaryAddress { get; set; }
    }
}

Next, modify the context class as follows:

using Microsoft.EntityFrameworkCore;
namespace EFCoreCodeFirstDemo.Entities
{
    public class EFCoreDbContext : DbContext
    {
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            //Configuring the Connection String
            optionsBuilder.UseSqlServer(@"Server=LAPTOP-6P5NK25R\SQLSERVER2022DEV;Database=EFCoreDB;Trusted_Connection=True;TrustServerCertificate=True;");
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            //Email is an Alternate Key, Applying Unique Constraints
            modelBuilder.Entity<Employee>()
            .HasAlternateKey(p => p.Email);

            //Create an index on the RegdNumber column
            modelBuilder.Entity<Employee>()
                .HasIndex(p => p.RegdNumber)
                .IsUnique(); //Make the index unique and by default non-clustered

            //Single-Column Primary Key
            modelBuilder.Entity<Employee>()
                .HasKey(p => p.EmpId);

            //Exclude TemporaryAddress property from mapping
            modelBuilder.Entity<Employee>()
                .Ignore(p => p.TemporaryAddress);
        }

        public DbSet<Employee> Employees { get; set; }
    }
}

In this example, we configure the Employee entity with an alternate key or Unique Key on the Email property, a unique index on the RegdNumber property, a primary key on the EmpId property, and exclude the TemporaryAddress property from mapping to the database.

With the above changes, open the Package Manager Console and Execute the add-migration and update-database commands as follows. You can give any name to your migration. Here, I am giving EFCoreDBMig3. The name that you are giving it should not be given earlier.

Entity Configurations using Entity Framework Core Fluent API

Now, if you verify the database, you should see the following.

Entity Configurations using EF Core Fluent API

How to Create a Table without Primary Key using EF Core Fluent API?

In Entity Framework (EF) Core, it’s a common practice to define a primary key for each table, as primary keys uniquely identify rows in a table. However, there are scenarios where you might want to create a table without a primary key, such as mapping to an existing database table or dealing with a non-standard database schema. You can achieve this using EF Core’s Fluent API by configuring the entity as a keyless entity.

Let us see how we can create a table without a primary key using EF Core Fluent API. Define the entity class without a primary key. Create a class file with the name TableWithOutPrimary key. The following entity will represent the table without a primary key.

namespace EFCoreCodeFirstDemo.Entities
{
    public class TableWithoutPrimaryKey
    {
        public string Name { get; set; }
        public string Email { get; set; }
        public string Address { get; set; }
        // Other properties...
    }
}

Next, modify the context class as follows. In our DbContext class, we need to override the OnModelCreating method and use the Fluent API to configure the entity as a keyless entity using the HasNoKey method:

using Microsoft.EntityFrameworkCore;
namespace EFCoreCodeFirstDemo.Entities
{
    public class EFCoreDbContext : DbContext
    {
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            //Configuring the Connection String
            optionsBuilder.UseSqlServer(@"Server=LAPTOP-6P5NK25R\SQLSERVER2022DEV;Database=EFCoreDB;Trusted_Connection=True;TrustServerCertificate=True;");
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<TableWithoutPrimaryKey>()
                    .HasNoKey(); // Configure the entity as a keyless entity
        }

        public DbSet<TableWithoutPrimaryKey> TablesWithoutPrimaryKey { get; set; }
    }
}

With the above changes, open the Package Manager Console and Execute the add-migration and update-database commands as follows. You can give any name to your migration. Here, I am giving EFCoreDBMig4. The name that you are giving it should not be given earlier.

How to Create a Table without Primary Key using EF Core Fluent API?

Now, if you verify the database, you should see the following.

How to Create a Table without Primary Key using EF Core Fluent API?

In the next article, I will discuss Configuring Primary Key and Composite Primary Key using Entity Framework Core Fluent API with Examples. In this article, I try to explain Entity Mappings using Entity Framework Core Fluent API with Examples. I hope you enjoyed this Entity Configurations using EF Core Fluent API article.

Leave a Reply

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