codelessgenie guide

Using Entity Framework Core with C#: A Beginner's Guide

If you’ve ever built a C# application that needs to interact with a database, you’ve probably faced the tedious task of writing SQL queries, managing connections, and mapping database tables to C# objects manually. Enter **Entity Framework Core (EF Core)**—a lightweight, open-source Object-Relational Mapper (ORM) that simplifies database interactions by letting you work with C# objects instead of raw SQL. EF Core eliminates boilerplate code, reduces errors, and lets you focus on your application’s logic rather than database plumbing. Whether you’re building a console app, a web API, or a desktop application, EF Core is a powerful tool to add to your toolkit. This guide is designed for beginners with basic C# knowledge. We’ll walk through setting up EF Core, creating models, connecting to a database, performing CRUD (Create, Read, Update, Delete) operations, and managing database schema changes with migrations. By the end, you’ll be able to build a functional data-driven application with EF Core.

Table of Contents

  1. Prerequisites
  2. What is Entity Framework Core?
  3. Setting Up EF Core
  4. Creating a Data Model
  5. The DbContext: Your Gateway to the Database
  6. Connecting to a Database
  7. CRUD Operations with EF Core
  8. Managing Database Schema with Migrations
  9. Conclusion
  10. References

Prerequisites

Before we start, ensure you have the following:

  • .NET SDK: Install the latest .NET SDK (v6.0 or later recommended).
  • Code Editor: Use Visual Studio (Community Edition is free) or VS Code with the C# extension.
  • Basic C# Knowledge: Familiarity with classes, objects, and LINQ (Language Integrated Query) will help.

What is Entity Framework Core?

Entity Framework Core is an ORM— a tool that bridges the gap between object-oriented programming (OOP) and relational databases. It allows you to:

  • Map C# classes (entities) to database tables.
  • Query data using LINQ instead of SQL.
  • Insert, update, and delete records using C# objects.
  • Automatically generate database schemas from your C# models.

In short, EF Core acts as a middleman, translating your C# code into SQL and vice versa.

Setting Up EF Core

Step 1: Install .NET SDK

If you haven’t already, install the .NET SDK. Verify the installation by running this command in your terminal:

dotnet --version  

You should see a version number (e.g., 7.0.100).

Step 2: Create a New Project

Let’s build a simple console app to demonstrate EF Core. Open your terminal and run:

dotnet new console -n EFCoreDemo  
cd EFCoreDemo  

This creates a new console project named EFCoreDemo and navigates into its folder.

Step 3: Install EF Core NuGet Packages

EF Core requires two main packages:

  1. EF Core Runtime: The core library (Microsoft.EntityFrameworkCore).
  2. Database Provider: A package specific to your database (e.g., SQL Server, SQLite, PostgreSQL).

For this guide, we’ll use SQLite (a lightweight, file-based database) because it requires no separate server setup. Install the required packages via the terminal:

dotnet add package Microsoft.EntityFrameworkCore  
dotnet add package Microsoft.EntityFrameworkCore.Sqlite  

If you prefer SQL Server, use Microsoft.EntityFrameworkCore.SqlServer instead.

Creating a Data Model

A model in EF Core is a C# class that represents a database table. Each property in the class maps to a column in the table. Let’s create a simple model for a Book entity.

Entity Classes

Add a new folder named Models in your project, then create a Book.cs file with the following code:

// Models/Book.cs  
namespace EFCoreDemo.Models;  

public class Book  
{  
    public int Id { get; set; }          // Primary Key  
    public string Title { get; set; }   // Book title  
    public string Author { get; set; }  // Author name  
    public int Pages { get; set; }      // Number of pages  
    public decimal Price { get; set; }  // Price  
}  

Here, Book is our entity. By convention:

  • Id is the primary key (EF Core automatically recognizes Id or BookId as the primary key).
  • Other properties (e.g., Title, Author) map to columns in the Books table (EF Core pluralizes class names for table names by default).

Data Annotations for Model Configuration

Sometimes, you need to customize how entities map to the database (e.g., set a column name, mark a field as required). Use data annotations to configure your model:

using System.ComponentModel.DataAnnotations;  
using System.ComponentModel.DataAnnotations.Schema;  

namespace EFCoreDemo.Models;  

public class Book  
{  
    [Key]  // Explicitly mark as primary key (optional, but clear)  
    public int BookId { get; set; }  // Custom primary key name  

    [Required]  // Ensures the column is NOT NULL  
    [MaxLength(200)]  // Limits title length to 200 characters  
    public string Title { get; set; }  

    [Column("Writer")]  // Maps to a database column named "Writer" instead of "Author"  
    public string Author { get; set; }  

    [Range(1, 2000)]  // Ensures Pages is between 1 and 2000  
    public int Pages { get; set; }  

    [Column(TypeName = "decimal(18,2)")]  // Sets SQL data type (e.g., for currency)  
    public decimal Price { get; set; }  
}  

The DbContext: Your Gateway to the Database

What is DbContext?

The DbContext class is the heart of EF Core. It:

  • Manages database connections.
  • Tracks changes to entities (e.g., when you add or update an object).
  • Provides access to database tables via DbSet<T> properties.

Think of DbContext as a “session” with the database.

Configuring DbContext

Create a Data folder in your project, then add a AppDbContext.cs file:

using Microsoft.EntityFrameworkCore;  
using EFCoreDemo.Models;  

namespace EFCoreDemo.Data;  

public class AppDbContext : DbContext  
{  
    // DbSet<T> represents a table in the database.  
    public DbSet<Book> Books { get; set; }  

    // Configure the database connection  
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)  
    {  
        // Use SQLite and specify the database file path  
        optionsBuilder.UseSqlite("Data Source=EFCoreDemo.db");  
    }  
}  
  • DbSet<Book> Books: Represents the Books table in the database. You’ll use this to query, add, update, or delete Book entities.
  • OnConfiguring: Configures the database provider (SQLite in this case) and connection string.

Connecting to a Database

Choosing a Database Provider

EF Core supports multiple databases (SQL Server, PostgreSQL, MySQL, SQLite, etc.). Each requires a specific NuGet package:

DatabaseNuGet Package Name
SQL ServerMicrosoft.EntityFrameworkCore.SqlServer
SQLiteMicrosoft.EntityFrameworkCore.Sqlite
PostgreSQLNpgsql.EntityFrameworkCore.PostgreSQL
MySQLPomelo.EntityFrameworkCore.MySql

We’re using SQLite, so we already installed Microsoft.EntityFrameworkCore.Sqlite.

Setting Up a Connection String

A connection string tells EF Core how to connect to your database. For SQLite, it’s a file path (the database will be created automatically if it doesn’t exist).

In the OnConfiguring method above, we hardcoded the connection string:

optionsBuilder.UseSqlite("Data Source=EFCoreDemo.db");  

For production apps, never hardcode connection strings! Instead, store them in appsettings.json and use dependency injection. For simplicity, we’ll use the hardcoded approach here, but we’ll mention the better practice later.

CRUD Operations with EF Core

Now that we have a model and DbContext, let’s perform the four core database operations: Create, Read, Update, Delete.

Create: Adding Entities

To add a new Book to the database:

  1. Create a Book object.
  2. Add it to the DbSet<Book> (via AppDbContext).
  3. Call SaveChanges() to persist the change to the database.

Update Program.cs (the entry point of your console app) with this code:

using EFCoreDemo.Data;  
using EFCoreDemo.Models;  

// Create a new Book object  
var newBook = new Book  
{  
    Title = "The Great Gatsby",  
    Author = "F. Scott Fitzgerald",  
    Pages = 180,  
    Price = 12.99m  
};  

// Create a DbContext instance  
using (var context = new AppDbContext())  
{  
    // Add the book to the Books table  
    context.Books.Add(newBook);  

    // Save changes to the database  
    context.SaveChanges();  
    Console.WriteLine($"Added book with ID: {newBook.BookId}");  
}  

Run the app with:

dotnet run  

EF Core will create the EFCoreDemo.db file in your project folder and insert the new book.

Read: Querying Entities

To retrieve data, use LINQ queries on the DbSet<Book>. Here are common examples:

Get All Books

using (var context = new AppDbContext())  
{  
    var allBooks = context.Books.ToList();  
    Console.WriteLine("All Books:");  
    foreach (var book in allBooks)  
    {  
        Console.WriteLine($"- {book.Title} by {book.Author} (${book.Price})");  
    }  
}  

Get a Single Book by ID

using (var context = new AppDbContext())  
{  
    int bookId = 1; // Replace with the ID of the book you added  
    var book = context.Books.FirstOrDefault(b => b.BookId == bookId);  

    if (book != null)  
    {  
        Console.WriteLine($"Found: {book.Title}");  
    }  
    else  
    {  
        Console.WriteLine("Book not found.");  
    }  
}  

Filter Books with LINQ

Use Where to filter results (e.g., find all books by “J.K. Rowling”):

var rowlingBooks = context.Books  
    .Where(b => b.Author == "J.K. Rowling")  
    .OrderBy(b => b.Title)  
    .ToList();  

Update: Modifying Entities

To update an existing book:

  1. Retrieve the book from the database.
  2. Modify its properties.
  3. Call SaveChanges() to apply the update.
using (var context = new AppDbContext())  
{  
    int bookId = 1;  
    var bookToUpdate = context.Books.FirstOrDefault(b => b.BookId == bookId);  

    if (bookToUpdate != null)  
    {  
        bookToUpdate.Price = 14.99m; // Increase price  
        context.SaveChanges();  
        Console.WriteLine($"Updated price of {bookToUpdate.Title} to ${bookToUpdate.Price}");  
    }  
}  

Delete: Removing Entities

To delete a book:

  1. Retrieve the book.
  2. Remove it from the DbSet.
  3. Call SaveChanges().
using (var context = new AppDbContext())  
{  
    int bookId = 1;  
    var bookToDelete = context.Books.FirstOrDefault(b => b.BookId == bookId);  

    if (bookToDelete != null)  
    {  
        context.Books.Remove(bookToDelete);  
        context.SaveChanges();  
        Console.WriteLine($"Deleted book: {bookToDelete.Title}");  
    }  
}  

Managing Database Schema with Migrations

So far, we’ve let EF Core create the database schema automatically. But what if you modify your model later (e.g., add a PublicationYear property to Book)? You could delete the database and let EF Core recreate it, but that would lose data.

Migrations solve this problem. Migrations are a set of files that track changes to your model and let you apply those changes to the database schema incrementally.

What Are Migrations?

Migrations:

  • Generate SQL scripts to update the database schema.
  • Preserve existing data (when possible).
  • Let you roll back changes if needed.

Creating and Applying Migrations

Step 1: Install the EF Core Tools

First, install the EF Core CLI tools (required to work with migrations):

dotnet tool install --global dotnet-ef  

Step 2: Create Your First Migration

Let’s modify the Book model to add a PublicationYear property:

public class Book  
{  
    // ... existing properties ...  
    public int PublicationYear { get; set; } // New property  
}  

Now, create a migration to reflect this change:

dotnet ef migrations add AddPublicationYearToBook  
  • add: The command to create a migration.
  • AddPublicationYearToBook: A descriptive name for the migration.

EF Core will generate a new folder Migrations with files like 20240101000000_AddPublicationYearToBook.cs (the timestamp ensures order).

Step 3: Apply the Migration

Run the migration to update the database schema:

dotnet ef database update  

EF Core will execute the SQL in the migration file, adding the PublicationYear column to the Books table.

Step 4: Verify the Change

Check the database to confirm the column was added. You can use tools like DB Browser for SQLite to open EFCoreDemo.db and inspect the Books table.

Conclusion

Congratulations! You’ve learned the basics of Entity Framework Core:

  • Setting up EF Core and connecting to a database.
  • Creating models and DbContext.
  • Performing CRUD operations with LINQ.
  • Managing schema changes with migrations.

EF Core is a vast library, and there’s much more to explore (e.g., relationships between entities, advanced querying, dependency injection). But with this foundation, you can start building data-driven C# apps with confidence.

References

Happy coding! 🚀