.NET Core | EF Core

Karim Samir
simplifycoding
Published in
7 min readMar 27, 2024

Practice 👨‍💻

1. Creating .Core Console Application

2. Install (on NuGet Package Manager):

· Microsoft.EntityFrameworkCore.SqlServer

· Microsoft.EntityFrameworkCore.Tools

3. Modeling the database

Creating a simple class Product:

EF Core will map that entity class to a table in the database

4. DBContext class

Creating a simple class EFContext.

This class is responsible for :

· Connecting to the database

· Querying & updating the database.

· Hold the Information needed to configure the database etc.

using Microsoft.EntityFrameworkCore;


public class EFContext: DbContext
{
public EFContext() { }

public EFContext(DbContextOptions<EFContext> options)
: base(options) { }

private const string connectiostring = "Server=serverName;Database=EFCore;Trusted_Connection=True;TrustServerCertificate=True";

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(connectiostring);
}

public DbSet<Product> Products { get; set; }
}

5. Creating the database

Now, our model is ready. The model has one entity type Product. We have created EFContext class to manage the Model. We have defined the DbSet Property of the Product so that it is included in the Model. Now it is time to create the database.

On Tools → NuGet Package Manager > Package Manager Console:

  • Add-Migration ‘NewDatabase’
    (For removing Last Migration: remove-migration)
  • Update-Database

More: https://www.learnentityframeworkcore.com/migrations

Result

NOTE : Trying to set-up Entity Framework core in .Net Standard project is an ERROR :

CRUD Operations

CRUD Operations Advanced

Add(): The DbContext.Add and DbSet.Add methods attach an entity graph to a context and set Added EntityState to a root and child entities, irrespective of whether they have key values or not.

Example:

Update(): The DbContext.Update() and DbSet.Update() methods attach an entity graph to a context and set the EntityState of each entity in a graph depending on whether it contains a key property value or not

Example:

Remove(): The DbContext.Remove() and DbSet.Remove() methods set the Deleted EntityState to the root entity.

Attach(): The DbContext.Attach() and DbSet.Attach() methods attach the specified disconnected entity graph and start tracking it. They return an instance of EntityEntry, which is used to assign the appropriate EntityState.

DBSet

Every entity model (Table) must declare a DbSet property in the DbContext. EF Core builds the database by inspecting the DbSet Property using the reflection. It then creates tables for these types.

For Entity Classes to be mapped to the database, they need to follow few conventions

· The class must be declared as public.

· Static classes are not allowed. The EF must be able to create an instance of the class.

· The Class should not have any constructor with a parameter. The parameter less constructor is allowed.

Configuring the Model(tables)

Database Schema Name Convention

EF Core creates the database using the schema is dbo.

Column Name

Table Columns names are named after the property name. The property must have a public getter. The setter can have any access mode.

Data types and column length

Primary Key Convention

Entity Framework Core does not allow you to create the tables without the primary key. It follows the convention to identify the candidate for the Primary Key. It searches any property with the name ID or <className>ID and uses it as Primary Key (If the model contains both id & <className>ID columns, then id is chosen as Primary key)

Foreign Key Convention

Indexes

Indexes for Foreign key is automatically created by the EF Core

Table Name Attribute

Table Schema Attribute

Column Name Attribute

Column Type Attribute

Column Order Attribute

Key Attribute

Composite Primary Key

ConcurrencyCheck Attribute

We decorate the StudentName Property with the ConcurrencyCheck attribute. When Entity Framework generates an update or delete statement, it always includes the StudentName column in where clause.

This attribute does not affect the database mapping in any way. This attribute is like timestamp attribute.

DatabaseGeneratedOption.Computed

Result:

DatabaseGeneratedOption.Identity

Result:

DatabaseGeneratedOption.None

is the default option, indicating that the database does not generate the property value. It’s typically used for properties you want to set in your application manually.

ForeignKey Attribute

Result:

NotMapped Attribute

Result:

InverseProperty Attribute

Problem Solved By InverseProperty:

In the This example, the Course and Teacher entities have two one-to-many relationships. A Course can be taught by an online teacher as well as a class-room teacher. In the same way, a Teacher can teach multiple online courses as well as class room courses.

Here, EF API cannot determine the other end of the relationship. It will throw the following exception for the above example during migration.

Unable to determine the relationship represented by navigation property ‘Course.OnlineTeacher’ of type ‘Teacher’. Either manually configure the relationship, or ignore this property using the ‘[NotMapped]’ attribute or by using ‘EntityTypeBuilder.Ignore’ in ‘OnModelCreating’.

Fluent API — Relationship

One To One

One to Many

Many to Many Relationship:

This feature is not supported in EF Core. In EF Core, we must create joining entity class and then setup two one to many relationship with the joining entity.

public class User
{
public int UserId { get; set; }
public string Name { get; set; }

// Navigation property
public ICollection<Right> Rights { get; set; }
}

public class Right
{
public int RightId { get; set; }
public string RightName { get; set; }

// Navigation property
public ICollection<User> Users { get; set; }
}

public class ApplicationDbContext : DbContext
{
public DbSet<User> Users { get; set; }
public DbSet<Right> Rights { get; set; }

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// Many-to-many relationship between User and Right
modelBuilder.Entity<User>()
.HasMany(u => u.Rights)
.WithMany(r => r.Users)
.UsingEntity(j => j.ToTable("UserRights")); // Optional: Name of the join table
}
}

How to delete and recreate from scratch an existing EF Code First database

1) Manually delete your DB — wherever it is (I’m assuming you have your connection sorted), or empty it, but easier/safer is to delete it all together — as there is system __MigrationHistory table - you need that removed too.

2) Remove all migration files - which are under Migrations - and named like numbers etc. - remove them all,

3) Rebuild your project containing migrations (and the rest) — and make sure your project is set up (configuration) to build automatically (that sometimes may cause problems — but not likely for you),

4) Run Add-Migration Initial again - then Update-Database

--

--