Configurations in Entity Framework Core

Configurations in Entity Framework Core

Entity Framework Core Configurations allow us to override the default conventions in order to create database schema and mappings. We already saw the concept of Conventions in Entity Framework Core where we understood how default conventions work. If we want to override the conventions then apply the configurations and customize the EF Core model to database mappings.

There are 2 Entity Framework Core Configuration Methods:

  • 1. Data Annotation Attributes
  • 2. Fluent API

Let us understand them one by one.

Data Annotation Attributes

These are the .NET Attributes that can be applied to the Entity classes and their properties. The Data Annotation attributes are included in separate namespace called System.ComponentModel.DataAnnotations.

Let me demonstrate how to apply these Data Annotation Attributes to the Entity classes in order to configure database tables and override the default Conventions of Entity Framework Core.

In the below code we have applied Data Annotation Attributes to the 2 classes (Country & City) and their properties.

[Table("TBL_City")]
public class City
{
    [Key]
    public int KeyId { get; set; }
 
    [Column("CityName", TypeName = "varchar(25)")]
    public string Name { get; set; }
 
    [NotMapped]
    public int Population { get; set; }
 
    [ForeignKey("FKid")]
    public Country Country { get; set; } 
}

[Table("TBL_Country")]
public class Country
{
    [Key]
    public int KeyId { get; set; }
 
    [MaxLength(20)]
    public string Name { get; set; }
}

Once we apply Entity Framework Core Migration then 2 database tables will be created due to [Table("Name")] attribute on the classes. These tables are:

  • 1. TBL_City
  • 2. TBL_Country
Data Annotation Attributes are widely used in validating input controls placed on the view. We have covered there uses in the article called Model Validation in ASP.NET Core from Beginning to Expert.

The table called TBL_City has:

  • KeyId column as primary key.
  • CityName column with data type varchar(25).
  • FKid as foreign key column.
Since the Population property has [NotMapped] attribute so no column is made for it on the TBL_City table.

The table called TBL_Country has:

  • KeyId column as primary key.
  • Name column with data type nvarchar(20).

See the below image which shows the snapshot of these 2 database tables.

entity framework core data annotations title=

Common Entity Framework Core Data Annotations

Attribute Description
Table Applied on entity class to give a name to database table.
Column Applied on a property to give column name, order and data type.
Key Sets the property as primary key for the table.
ForeignKey Applied to a property to mark it as foreign key.
NotMapped Can be applied to entity class or property for not generating a corresponding table or column in the database.
MaxLength Sets the max length for the table column.
Required Can be applied on properties to make the corresponding column on the table as not null.

Table schema

Different databases use different schemas. For example the Microsoft SQL Server will use the “dbo” schema. We can change the scheme for the database by the Schema property of [Table] attribute.

See below entity. When migrations are performed then the table called us.TBL_City is created.

[Table("TBL_City", Schema = "us"))]
public class City
{
    public int Id { get; set; }
  
    public string Name { get; set; }
}

Primary Key and Composite Key

Any property of an entity can be made the primary key by applying the [Key] attribute on it. Example:

public class City
{
    [Key]
    public int Id { get; set; }
  
    public string Name { get; set; }
}

It should also be noted that the “int” type primary key in SQL Server is automatically set up to be an IDENTITY column i.e. IDENTITY (1, 1).

Non-key properties can be configured to have its value generated for every inserted row as shown below. So StudentRollNo will start with 1, 2, 3, ….

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Int StudentRollNo { get; set; }

We can disable this auto setup of Identity Column by applying the [DatabaseGenerated] attribute as shown below.

public class City
{
    [Key]   
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int Id { get; set; }
  
    public string Name { get; set; }
}

In the below example the Name field will be the primary key and will overwrite the conventions which states that the “Id” column would not be the primary key had we applied the [Key] attribute on the Name field.

public class City
{
    public int Id { get; set; }
  
    [Key]
    public string Name { get; set; }
}

We can also configure multiple properties to be the composite key of an entity. This is done by applying the [PrimaryKey] attribute on the class. In the below example State and Population fields will together form the composite key for the City table and City entity.


[PrimaryKey(nameof(State), nameof(Population))]
public class City
{
    public int Id { get; set; }
  
    public string Name { get; set; }

    public string State { get; set; }

    public string Population { get; set; }
}

[NotMapped] attribute – Excluding from migrations

If we don’t want the database table to be created for an entity on migration then we can use the [NotMapped] attribute.

In the below code we have applied the [NotMapped] attribute on the CityInfo class. This will tell EF Core to not create a table in the database for this entity during migrations.

[NotMapped]
public class CityInfo
{
    public int Id { get; set; }
  
    public string Name { get; set; }
}

We can also use NotMapped attribute to prevent database table columns to be created for certain properties of the entity classes.

public class City
{
    public int Id { get; set; }
  
    public string Name { get; set; }

    [NotMapped]
    public string State { get; set; }

    [NotMapped]
    public string Population { get; set; }
}

In the above code the City database table will be created on migration but the “State” and “Population” columns will not be created. That is the City table will only have Id and Name columns.

[Keyless] attribure – Entities not containing a key

Entities that don’t have a key must be attributed with [Keyless] attribute. Example:

[Keyless]
public class EmpDep
{
    public string Name { get; set; }
    public string Designation { get; set; }
    public string DName { get; set; }
}

The above EmpDep class has “Keyless” attribute since their is no “Id” property in it. So EF core will not track it. Keyless entities are mostly used for reading data from database Views or Table-Valued Functions.

In a relationship like One-One, One-Many and Many-Many the keyless entity cannot act as the principal end of a relationship, since there is no principal key for the foreign keys to reference. However, keyless entity types can still have foreign keys defined, and hence can act as the dependent end of a relationship.

Fluent API

Another way to configure domain classes is by using Entity Framework Fluent API. You will learn about Fluent API by reading these 4 tutorials.

SHARE THIS ARTICLE

  • linkedin
  • reddit
yogihosting

ABOUT THE AUTHOR

I hope you enjoyed reading this tutorial. If it helped you then consider buying a cup of coffee for me. This will help me in writing more such good tutorials for the readers. Thank you. Buy Me A Coffee donate