Adapting and Extending an EF Core 8 Project - Publisher App Example
This post showcases how to take a project from the Pluralsight EF Core 8 Fundamentals GitHub repo and make a few tweaks to it.
This post serves as a reminder to oneself of completing the EF Core 8 Fundamentals course this week.
Adapt
The first step is to choose a project and download the folder that contains it, for example, this one. There are tools such as this to download a single folder instead of the whole repo.
The second step is to initialise a Git repository, which is done in this commit. The borrowed code is left as is, with only .gitignore
and README.md
files added.
The third step is to set up a SQL Server. A cross-platform way to do so is via Docker. Here is an example command to run SQL Server from a Docker container:
docker run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=mospec-6teXxo-wiwgec" \
-p 1433:1433 --name publisherappsqlserver --hostname publisherappsqlserver \
-d \
mcr.microsoft.com/mssql/server:2022-latest
The fourth step is to modify the connection string to point to this SQL Server, which is done in this commit.
Now the database can be initialised with the command dotnet ef --project ../PublisherData database update
run from the PubAPI
project.
The result is a running app. Here is an example of calling the endpoint to get authors with books:
Extend
The first extension is to introduce complex properties, such as Person Name, which is done in this commit.
There is an inconvenience: EF8 currently does not support complex properties together with seeding via the HasData
method. A workaround is to remove all data seeding with HasData
, then add the migration, then manually edit the migration to avoid deleting previously seeded data.
The second extension is to introduce request/response DTOs for all author endpoints, which is done in this commit. It is also convenient to keep all DTO classes as private nested classes within the AuthorEndpoints
class.
In particular, getting authors with books requires two mappings, one for authors and one for books:
return await db.Authors.Include(a => a.Books).AsNoTracking()
.Select(x => new AuthorWithBookResponse
{
AuthorId = x.AuthorId,
FirstName = x.Name.FirstName,
LastName = x.Name.LastName,
Books = x.Books.Select(x => new BookResponse(x.BookId, x.Title, x.PublishDate)).ToList()
}).ToListAsync();
As a result, calling the endpoint to get authors with books no longer returns irrelevant data: