Modeling Users and Posts with C# and Entity Framework Core in ASP.NET Core Web API

Introduction

Creating a RESTful API with ASP.NET Core is a popular choice among developers who work with C#. In this tutorial, we will walk through modeling two entities—users and Posts—using Entity Framework Core (EF Core) and then expose them via a REST API.

Prerequisites

  • .NET SDK installed

  • A text editor or IDE of your choice

  • Basic knowledge of C#, REST, and Entity Framework

Setting Up Your Project

First, create a new ASP.NET Core Web API project:

dotnet new webapi -n UserPostApi

Add the EF Core package for SQL Server:

cd UserPostApi
dotnet add package Microsoft.EntityFrameworkCore
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet add package Microsoft.EntityFrameworkCore.Sqlite

Creating Models

We'll start by defining our User and Post models. Create a folder named. Models And add two classes: User.cs and Post.cs.

User.cs

public class User
{
    public int UserId { get; set; }
    public string Username { get; set; }
    public string Email { get; set; }
    public List<Post> Posts { get; set; }
}

Post.cs

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }
    public int UserId { get; set; }
    public User User { get; set; }
}

Configuring DbContext

Create a new file AppDbContext.cs:

using Microsoft.EntityFrameworkCore;

public class AppDbContext : DbContext
{
    public DbSet<User> Users { get; set; }
    public DbSet<Post> Posts { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
         optionsBuilder.UseSqlite("Data Source=app.db"));
    }
}

Creating Controllers

Generate API controllers for your models.

UsersController.cs

[ApiController]
[Route("api/[controller]")]
public class UsersController : ControllerBase
{
    private readonly AppDbContext _context;
    public UsersController(AppDbContext context)
    {
        _context = context;
    }

    [HttpGet]
    public ActionResult<List<User>> GetAll()
    {
        return _context.Users.ToList();
    }

    // Add this method to handle POST requests for creating a new user
    [HttpPost]
    public async Task<ActionResult<User>> Create(User user)
    {
        _context.Users.Add(user);
        await _context.SaveChangesAsync();

        return CreatedAtAction(nameof(GetById), new { id = user.Id }, user);
    }

    // Optionally add this method to retrieve a single user by ID
    [HttpGet("{id}")]
    public ActionResult<User> GetById(int id)
    {
        var user = _context.Users.FirstOrDefault(u => u.Id == id);
        if (user == null)
        {
            return NotFound();
        }
        return user;
    }

    // ... more CRUD operations
}

PostsController.cs

[ApiController]
[Route("api/[controller]")]
public class PostsController : ControllerBase
{
    private readonly AppDbContext _context;
    public PostsController(AppDbContext context)
    {
        _context = context;
    }

    [HttpGet]
    public ActionResult<List<Post>> GetAll()
    {
        return _context.Posts.ToList();
    }

    // Add this method to handle POST requests
    [HttpPost]
    public async Task<ActionResult<Post>> Create(Post post)
    {
        _context.Posts.Add(post);
        await _context.SaveChangesAsync();

        return CreatedAtAction(nameof(GetById), new { id = post.Id }, post);
    }

    // Optionally add this method to retrieve a single post by ID
    [HttpGet("{id}")]
    public ActionResult<Post> GetById(int id)
    {
        var post = _context.Posts.FirstOrDefault(p => p.Id == id);
        if (post == null)
        {
            return NotFound();
        }
        return post;
    }

   // ... more CRUD operations
}

Understanding Primary and Foreign Keys

EF Core identifies primary keys and foreign keys through conventions, data annotations, or Fluent API configurations.

For example, by convention:

  • UserId in the User class is considered a primary key.

  • UserId in the Post class is regarded as a foreign key.

You can also explicitly set these keys using Data Annotations or Fluent API.

Testing the API

Run your API and use Postman or a similar tool to test the endpoints:

  • dotnet ef migrations add initial

  • dotnet ef database update

  • Test Endpoints

Summary

We built a simple REST API using ASP.NET Core, modeled our Users and Posts entities, and configured the database context using Entity Framework Core. This example is a foundational step to building more complex and feature-rich APIs.

Happy Hacking 🏗️

Did you find this article valuable?

Support justjordant by becoming a sponsor. Any amount is appreciated!