Paramclasses Academy - Blog

Tutorials Details

←
Post 29 of 30
→

What is Entity Framework Core ? Explain: Database Operations with C#

What is Entity Framework Core ? Explain: Database Operations with C#

October 26, 2026

Introduction

Modern applications need to store and manage data. For example, a student management system stores student names, email addresses, courses, and enrollment details in a database.

C# applications can interact with databases using SQL queries, but writing SQL manually for every database operation can become repetitive. Entity Framework Core (EF Core) makes database development easier by allowing developers to work with C# objects and LINQ queries.

In this tutorial, you will learn how Entity Framework Core works, how to connect a C# application to SQL Server, and how to perform essential database operations.

1. What Is Entity Framework Core?

Entity Framework Core is a modern, open-source Object-Relational Mapper (ORM) for .NET.

An ORM maps application objects to relational database tables. Instead of manually writing SQL for every operation, developers can use C# classes and methods to interact with database data.

For example, you can represent a student using a C# class:

public class Student
{
    public int Id { get; set; }
    public string Name { get; set; } = string.Empty;
    public string Email { get; set; } = string.Empty;
}

EF Core can map this class to a database table. Each Student object represents a record, while its properties correspond to table columns.

Key benefits of EF Core

  • Less repetitive SQL: Use C# code for common database operations.

  • LINQ support: Filter, sort, and query data using familiar C# expressions.

  • Migrations: Track and apply changes to your database schema.

  • Change tracking: Detect modifications to loaded entities.

  • Multiple database providers: Work with SQL Server, SQLite, PostgreSQL, and other supported databases.

  • Asynchronous operations: Use async methods for database queries and updates.

2. Entity Framework Core vs ADO.NET

ADO.NET and EF Core are both used to access databases, but their approaches differ.

Feature ADO.NET Entity Framework Core
Main approach Database commands and data readers Objects and ORM mapping
SQL writing Often written manually Generated for many operations; raw SQL is also supported
Querying SQL commands and data APIs LINQ and EF Core APIs
Schema changes Managed through database tools or scripts Supports migrations
Best suited for Direct database control and lower-level access Object-oriented data access and application development

EF Core does not eliminate SQL knowledge. Understanding SQL, tables, keys, and relationships remains valuable when building database-driven applications.

3. Prerequisites

Before starting, make sure you have:

  • Visual Studio or another suitable .NET IDE.

  • A supported .NET SDK.

  • SQL Server or SQL Server LocalDB.

  • Basic C# knowledge.

  • Basic understanding of relational databases.

For this tutorial, we will build a small console application using SQL Server.

4. Create a C# Project

Open a terminal and run:

dotnet new console -n EfCoreDemo
cd EfCoreDemo

Install the SQL Server provider for EF Core:

dotnet add package Microsoft.EntityFrameworkCore.SqlServer

To use EF Core migrations from the .NET CLI, also install the design package:

dotnet add package Microsoft.EntityFrameworkCore.Design

Install the EF Core command-line tool if it is not already available:

dotnet tool install --global dotnet-ef

If the tool is already installed, update it instead:

dotnet tool update --global dotnet-ef

Use compatible EF Core package versions that support your target .NET version. Keep the EF Core provider, design package, and tooling on compatible major versions.

5. Create the Student Model

Create a file named Student.cs:

namespace EfCoreDemo;

public class Student
{
    public int Id { get; set; }

    public string Name { get; set; } = string.Empty;

    public string Email { get; set; } = string.Empty;

    public int Age { get; set; }
}

Understanding the model

  • Id is the primary key by EF Core convention.

  • Name stores the student's name.

  • Email stores the student's email address.

  • Age stores the student's age.

EF Core uses conventions to determine common mappings. You can also customize column names, constraints, relationships, and other schema details through data annotations or Fluent API configuration.

6. Create the DbContext

A DbContext represents a session with the database. It manages entity objects, tracks changes, and sends queries and updates to the database.

Create AppDbContext.cs:

using Microsoft.EntityFrameworkCore;

namespace EfCoreDemo;

public class AppDbContext : DbContext
{
    public DbSet<Student> Students => Set<Student>();

    protected override void OnConfiguring(
        DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer(
            "Server=(localdb)\\MSSQLLocalDB;" +
            "Database=EfCoreDemoDb;" +
            "Trusted_Connection=True;" +
            "TrustServerCertificate=True;");
    }
}

Understanding the code

  • DbContext is the base class for the database context.

  • DbSet<Student> represents the collection of student entities.

  • UseSqlServer() configures EF Core to use SQL Server.

  • The connection string identifies the database server and database.

Important: This connection string is a local development example for SQL Server LocalDB. The server name and authentication settings must match your environment. TrustServerCertificate=True should not be copied blindly into production configurations; use an appropriate trusted certificate configuration.

For production applications, store connection strings in configuration or a secure secret-management system rather than hardcoding credentials in source code.

7. Create the Database Using Migrations

EF Core migrations allow you to create and update a database schema based on your model.

First, make sure the project builds:

dotnet build

Create the first migration:

dotnet ef migrations add InitialCreate

Apply the migration to the database:

dotnet ef database update

EF Core will create the database if it does not exist and apply the schema changes described by the migration, assuming the connection and permissions are valid.

The migration normally creates a Students table containing columns corresponding to the model properties.

Why are migrations useful?

Suppose you later add a PhoneNumber property to the Student class. You can create another migration to record that schema change:

dotnet ef migrations add AddStudentPhoneNumber
dotnet ef database update

Review generated migrations before applying them, especially against production databases. Schema changes can affect existing data and application compatibility.

8. Insert Data into the Database

Add the following code to Program.cs:

using EfCoreDemo;

using var db = new AppDbContext();

var student = new Student
{
    Name = "Amit Sharma",
    Email = "amit@example.com",
    Age = 21
};

db.Students.Add(student);

db.SaveChanges();

Console.WriteLine("Student saved successfully!");
Console.WriteLine($"Student ID: {student.Id}");

How it works

  1. The application creates a database context.

  2. A new Student object is created.

  3. Add() marks the student for insertion.

  4. SaveChanges() sends the pending change to the database.

  5. If the database generates the primary key, EF Core can populate student.Id after a successful save.

Expected output:

Student saved successfully!
Student ID: 1

The exact ID can differ depending on existing database records.

9. Read Data from the Database

You can retrieve all students using LINQ:

using EfCoreDemo;
using Microsoft.EntityFrameworkCore;

using var db = new AppDbContext();

var students = db.Students
    .AsNoTracking()
    .OrderBy(s => s.Name)
    .ToList();

foreach (var student in students)
{
    Console.WriteLine(
        $"{student.Id} - {student.Name} - {student.Email} - {student.Age}");
}

AsNoTracking() is useful for read-only queries because EF Core does not need to track changes to the returned entities.

Find a student by ID

using EfCoreDemo;

using var db = new AppDbContext();

int studentId = 1;

var student = db.Students.Find(studentId);

if (student is not null)
{
    Console.WriteLine(student.Name);
}
else
{
    Console.WriteLine("Student not found.");
}

Find() looks for an entity with the specified primary key. It may return an entity already tracked by the current context without querying the database again.

10. Filter and Sort Data Using LINQ

LINQ lets you express queries using C# syntax.

Find students older than 20

var students = db.Students
    .Where(s => s.Age > 20)
    .ToList();

Find a student by email

string email = "amit@example.com";

var student = db.Students
    .FirstOrDefault(s => s.Email == email);

Sort students by age

var students = db.Students
    .OrderBy(s => s.Age)
    .ToList();

EF Core translates many LINQ expressions into SQL and executes the query on the database server. Translation support depends on the expression and provider. Avoid loading an entire table into memory when the database can perform the filtering itself.

11. Update Existing Data

Retrieve the student, change a property, and save the changes:

using EfCoreDemo;

using var db = new AppDbContext();

var student = db.Students.Find(1);

if (student is not null)
{
    student.Age = 22;

    db.SaveChanges();

    Console.WriteLine("Student updated successfully!");
}
else
{
    Console.WriteLine("Student not found.");
}

When the entity is tracked, EF Core detects the changed property. Calling SaveChanges() sends the update to the database.

For larger applications, consider concurrency handling when multiple users may edit the same record.

12. Delete Data from the Database

To delete a student:

using EfCoreDemo;

using var db = new AppDbContext();

var student = db.Students.Find(1);

if (student is not null)
{
    db.Students.Remove(student);

    db.SaveChanges();

    Console.WriteLine("Student deleted successfully!");
}
else
{
    Console.WriteLine("Student not found.");
}

Remove() marks the entity for deletion. The deletion is sent to the database when SaveChanges() executes successfully.

In a real application, confirm that the record should be deleted and consider authorization, related records, and database constraints before performing destructive operations.

13. Use Asynchronous Database Operations

In web applications and other responsive applications, asynchronous database operations can help avoid blocking the calling thread while waiting for database I/O.

For example:

using EfCoreDemo;
using Microsoft.EntityFrameworkCore;

await using var db = new AppDbContext();

var students = await db.Students
    .AsNoTracking()
    .OrderBy(s => s.Name)
    .ToListAsync();

foreach (var student in students)
{
    Console.WriteLine(student.Name);
}

Common asynchronous EF Core methods include:

  • ToListAsync()

  • FirstOrDefaultAsync()

  • SingleOrDefaultAsync()

  • FindAsync()

  • SaveChangesAsync()

Use await to wait for the operation to complete. Do not execute multiple concurrent operations on the same DbContext; use separate contexts when independent operations genuinely need to run concurrently.

14. Use Dependency Injection in ASP.NET Core

In ASP.NET Core applications, the typical approach is to configure the context through dependency injection rather than using OnConfiguring() directly.

In Program.cs:

using EfCoreDemo;
using Microsoft.EntityFrameworkCore;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddDbContext<AppDbContext>(options =>
    options.UseSqlServer(
        builder.Configuration.GetConnectionString("DefaultConnection")));

var app = builder.Build();

app.MapGet("/", () => "EF Core application is running!");

app.Run();

Add the connection string to appsettings.json:

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\MSSQLLocalDB;Database=EfCoreDemoDb;Trusted_Connection=True;TrustServerCertificate=True;"
  }
}

The example is intended for local development. Configure the server, authentication, and certificate settings for your actual environment. Do not store production passwords in source-controlled configuration files.

When using this approach, configure AppDbContext with the options-based constructor:

using Microsoft.EntityFrameworkCore;

namespace EfCoreDemo;

public class AppDbContext : DbContext
{
    public AppDbContext(DbContextOptions<AppDbContext> options)
        : base(options)
    {
    }

    public DbSet<Student> Students => Set<Student>();
}

ASP.NET Core creates and disposes contexts according to their configured lifetime, typically scoped to a request.

15. Common Errors and Solutions

Error 1: Unable to create a DbContext

Possible cause: EF Core tools cannot determine how to construct the context.

Solution: Check the context constructor, startup project, provider configuration, and design-time configuration.

Error 2: Cannot connect to SQL Server

Possible cause: SQL Server is unavailable, the instance name is incorrect, or authentication is misconfigured.

Solution: Verify that the database service is running and that your connection string matches the installed SQL Server instance.

Error 3: No migrations were found

Possible cause: A migration has not been created or the tooling is using the wrong project.

Solution: Run dotnet ef migrations add InitialCreate from the correct project directory and verify the startup and target projects when using a multi-project solution.

Error 4: Changes are not saved

Possible cause: SaveChanges() or SaveChangesAsync() was not called, or the operation failed.

Solution: Ensure that changes are saved and inspect any exception returned by the database operation.

Error 5: LINQ query cannot be translated

Possible cause: Some part of the expression is not supported by the database provider.

Solution: Rewrite the query using supported expressions or deliberately retrieve a limited result set before performing client-side processing.

16. Best Practices for EF Core

  1. Use asynchronous methods for I/O-bound operations in applications where async improves responsiveness.

  2. Keep contexts short-lived. Avoid using a single DbContext indefinitely.

  3. Use LINQ filtering on the server. Apply Where(), OrderBy(), and pagination before materializing results when appropriate.

  4. Use migrations carefully. Review generated SQL and schema changes before production deployment.

  5. Protect connection strings. Use secure configuration and secret management.

  6. Validate user input. Database constraints are important, but application-level validation also improves usability.

  7. Avoid exposing sensitive information. Do not return database credentials or raw exception details to end users.

  8. Use transactions when needed. Group related database changes when they must succeed or fail together.

  9. Handle errors and concurrency. Database operations can fail because of connectivity, constraints, or simultaneous updates.

  10. Understand the SQL being generated. EF Core is an abstraction, not a replacement for database fundamentals.

17. Practical Project: Student Management System

Build a simple Student Management System using C#, EF Core, and SQL Server.

Project features

  • Add a new student.

  • Display all students.

  • Search for a student by ID.

  • Update student details.

  • Delete a student.

  • Filter students by age.

  • Persist all records in SQL Server.

Suggested project structure

EfCoreDemo/
├── Models/
│   └── Student.cs
├── Data/
│   └── AppDbContext.cs
├── Migrations/
├── Program.cs
└── EfCoreDemo.csproj

For a larger application, keep models, data access, business logic, and user-interface code organized into separate files or projects.

Development steps

  1. Create the console project.

  2. Install the EF Core SQL Server provider.

  3. Create the Student model and AppDbContext.

  4. Configure the connection string.

  5. Create and apply the initial migration.

  6. Implement insert, read, update, and delete operations.

  7. Add LINQ filtering and sorting.

  8. Test behavior when a student does not exist or the database is unavailable.

Challenge: Extend the project with a Course model and associate students with courses. Decide whether your relationship should be one-to-many or many-to-many, then configure the appropriate foreign keys and navigation properties.

18. Knowledge Check

Q1. What does ORM stand for?

A. Object Runtime Manager
B. Object-Relational Mapper
C. Online Resource Model
D. Operational Record Method

Q2. Which class represents a session with the database in EF Core?

A. DbContext
B. Console
C. StringBuilder
D. HttpClient

Q3. Which method saves tracked changes to the database synchronously?

A. Add()
B. Find()
C. SaveChanges()
D. ToList()

Q4. Which command applies pending migrations to the database using the EF Core CLI?

A. dotnet build
B. dotnet ef database update
C. dotnet new console
D. dotnet restore

Q5. Why is AsNoTracking() useful for read-only queries?

A. It automatically deletes records.
B. It disables SQL Server.
C. It avoids change tracking for the returned entities.
D. It creates a migration.

Answers

  • Q1: B — Object-Relational Mapper.

  • Q2: A — DbContext.

  • Q3: C — SaveChanges().

  • Q4: B — dotnet ef database update.

  • Q5: C — It avoids change tracking for the returned entities.

19. Frequently Asked Questions

Is Entity Framework Core free?

Yes. EF Core is open-source software. Database hosting, commercial database editions, and other infrastructure may have separate costs.

Is EF Core the same as Entity Framework 6?

No. EF Core is a separate, modern ORM designed for .NET. Entity Framework 6 is a different product with its own capabilities and compatibility considerations.

Can EF Core work with SQL Server?

Yes. Install the Microsoft.EntityFrameworkCore.SqlServer provider and configure the database connection.

Do I need to learn SQL before learning EF Core?

You can begin learning EF Core with basic C# knowledge, but understanding SQL, relational tables, keys, joins, and indexes will help you write and troubleshoot better database applications.

Does EF Core automatically create a database?

It can create and update a database when configured appropriately, for example by applying migrations with dotnet ef database update. You must still configure a working provider, connection, and permissions.

Is EF Core suitable for large applications?

Yes, it is widely used in applications of varying sizes. Performance and maintainability depend on query design, indexing, context lifetime, data access patterns, and deployment practices.

Conclusion

Entity Framework Core makes database development in C# more convenient by mapping relational data to C# objects. You have learned how to create a model, configure a DbContext, apply migrations, perform CRUD operations, query data with LINQ, and use asynchronous database methods.

Practice these concepts by completing the Student Management System project. Understanding EF Core will also prepare you for building database-driven web applications with ASP.NET Core.

←
Post 29 of 30
→