Entity Framework Setup - GRAPHQL API IN .NET w/ HOT CHOCOLATE #5.1

SingletonSean
15 Jan 202211:33

Summary

TLDRThis tutorial video script guides viewers through setting up a GraphQL API with Hot Chocolate, focusing on integrating Entity Framework for data access. It covers installing necessary packages, creating DTOs and a DbContext, and configuring a SQLite database. The script also details the process of defining DbSets, applying migrations, and setting up automatic migration application on startup, providing a solid foundation for future GraphQL features like data loaders, pagination, and filtering.

Takeaways

  • πŸ› οΈ The video covers the setup of GraphQL operations using Hot Chocolate, focusing on data access services with Entity Framework.
  • πŸ“¦ It's necessary to install specific packages like 'HotChocolate.Data.EntityType' to integrate with Entity Framework and handle parallel resolver execution.
  • 🏒 The creation of a database context and Data Transfer Objects (DTOs) is essential to map GraphQL schema to the database structure.
  • πŸ“ A new folder structure is introduced with 'DTOs' and 'Services' to organize the project better and separate concerns.
  • πŸ”„ The script demonstrates the process of creating a 'SchoolDbContext' and defining 'DbSets' for each DTO to establish database tables.
  • πŸ”— The importance of establishing relationships, such as many-to-many between courses and students, is highlighted in the DTO setup.
  • πŸ“ The script guides through the migration creation process using Entity Framework Core commands in a .NET environment.
  • πŸ” It's crucial to ensure that the database context inherits from the DbContext class to function correctly with Entity Framework.
  • πŸ”„ The video shows troubleshooting steps when migrations fail, such as missing references or incorrect relationships in the schema.
  • πŸš€ The video concludes with the application of database migrations on startup using the host services in the 'Program.cs' file.
  • πŸ“š The script serves as a prerequisite for further GraphQL and Hot Chocolate exploration in subsequent parts of the series.

Q & A

  • What is the main focus of the video script?

    -The main focus of the video script is to demonstrate how to implement services for data access using Entity Framework in a GraphQL API with Hot Chocolate.

  • Why is it necessary to install the Hot Chocolate.Data.EntityFramework package?

    -The Hot Chocolate.Data.EntityFramework package is necessary because it allows for the execution of resolvers in parallel, which is a feature that is not supported by default in Entity Framework.

  • What are DTOs and why are they used in this context?

    -DTOs (Data Transfer Objects) are used to describe how data will be laid out in the database. They are used in this context to reflect the GraphQL schema and define the structure of data that will be accessed via the database.

  • What is the purpose of creating a separate folder for DTOs and Services in the project?

    -Creating separate folders for DTOs and Services helps in organizing the code better, separating concerns, and making the project structure more maintainable.

  • Why is it important to define DbSets in the DbContext?

    -Defining DbSets in the DbContext is important because it tells Entity Framework which entities should be represented as tables in the database.

  • What is the significance of moving the Subject enum to a separate layer?

    -Moving the Subject enum to a separate layer (models folder) centralizes the definition, making it easier to manage and reuse across different parts of the application, such as DTOs and the GraphQL schema.

  • Why is it necessary to create migrations for the database?

    -Creating migrations is necessary to manage changes in the database schema over time. It allows for the application of these changes in a controlled and reversible manner.

  • What package is needed to use SQLite with Entity Framework?

    -The package needed to use SQLite with Entity Framework is Microsoft.EntityFrameworkCore.Sqlite.

  • How can migrations be automatically applied on application startup?

    -Migrations can be automatically applied on application startup by using the Migrate method on the database within the DbContext during the application's initialization process.

  • What is the purpose of creating a PooledDbContextFactory?

    -Creating a PooledDbContextFactory is used to manage the lifecycle of DbContext instances, allowing for efficient reuse of database connections and improving performance.

  • How is the connection string for the database typically configured?

    -The connection string for the database is typically configured in the appsettings.json file under a 'ConnectionStrings' section, specifying details like the data source and database name.

Outlines

00:00

πŸ“š Setting Up GraphQL with Hot Chocolate and Entity Framework

This paragraph introduces the process of integrating GraphQL with Hot Chocolate and Entity Framework for data access in an application. The speaker discusses the necessity of using Hot Chocolate's data packages for parallel execution of resolvers, which is not natively supported by Entity Framework. The process includes installing necessary NuGet packages, creating a new folder for DTOs and services, and setting up a DbContext named SchoolDbContext. The paragraph also covers the creation of DTOs for Course, Student, and Instructor, reflecting the GraphQL schema and handling relationships and properties accordingly. The speaker also moves the Subject enum to a models layer to avoid direct schema references in DTOs.

05:02

πŸ”§ Configuring Entity Framework with SQLite and Applying Migrations

The second paragraph delves into the configuration of Entity Framework with SQLite as the database. The speaker explains the process of setting up a SQLite package, configuring the connection string from appsettings.json, and ensuring the SchoolDbContext inherits from DbContext. The paragraph details the creation of database migrations using the .NET CLI, addressing issues with the Subject enum's namespace, and making necessary adjustments to the GraphQL schema. The speaker corrects the many-to-many relationship between courses and students by adding a navigation property in the Student DTO and adjusts the Instructor DTO to reflect the relationship with courses. The paragraph concludes with the application of migrations during startup using a DbContext factory and the migration process in the Program.cs file.

10:04

πŸš€ Wrapping Up Database Setup and Previewing GraphQL Implementation

In the final paragraph, the speaker wraps up the database setup process, successfully generating the school.db file. The speaker reflects on the lengthy process and decides to split the tutorial into two parts, with the first part focusing on Entity Framework setup and the second part dedicated to GraphQL and Hot Chocolate features. The speaker invites viewers to skip the database setup if they already have one and looks forward to more engaging content in the next part of the series. The paragraph ends with an invitation for feedback, a call to action for viewers to become members, and an encouragement to like or subscribe for more content.

Mindmap

Keywords

πŸ’‘GraphQL

GraphQL is a query language for APIs and a runtime for executing those queries against your data. It's designed to provide a more efficient, flexible, and powerful alternative to traditional RESTful services. In the video, GraphQL is the central theme as the script discusses setting up a GraphQL API using Hot Chocolate, a GraphQL server library for .NET.

πŸ’‘Hot Chocolate

Hot Chocolate is a GraphQL server library for .NET that allows developers to easily implement GraphQL APIs. It is mentioned in the script as the tool used for setting up the GraphQL operations and for demonstrating advanced features such as data loaders, pagination, sorting, and filtering.

πŸ’‘Entity Framework

Entity Framework is an object-relational mapper (ORM) for .NET that enables developers to work with a database using .NET objects. It eliminates the need for most of the data-access code that developers usually need to write. In the script, Entity Framework is used for data access, allowing the services to interact with the database.

πŸ’‘Data Access

Data access refers to the methods and processes used to retrieve, insert, update, and delete data in a database. In the video script, implementing services for data access is a key step, which involves using Entity Framework to connect the GraphQL API with a database.

πŸ’‘DTOs (Data Transfer Objects)

DTOs are simple objects whose purpose is to transfer data between processes or components. In the script, DTOs such as Course DTO, Student DTO, and Instructor DTO are created to describe how data will be structured and transferred within the application.

πŸ’‘DbSet

DbSet is a class in Entity Framework that represents a collection of entities that can be queried and saved to a database. In the script, DbSets are defined for each DTO to inform the DbContext that a table should be created for each object in the database.

πŸ’‘DbContext

DbContext is a class in Entity Framework that represents a session with the database and allows querying and saving instances of your entities. In the script, a SchoolDbContext is created to manage the database operations for the application.

πŸ’‘Migrations

In Entity Framework, migrations are a way to apply changes to the database schema over time. The script describes creating an initial migration to set up the database schema and then applying that migration to the database.

πŸ’‘Many-to-Many Relationship

A many-to-many relationship is a type of database relationship where multiple records in one table can be associated with multiple records in another table, and vice versa. The script discusses setting up a many-to-many relationship between Courses and Students using a join table.

πŸ’‘SQLite

SQLite is a C-language library that implements a small, fast, self-contained, high-reliability, full-featured SQL database engine. It is mentioned in the script as the choice for the database setup due to its ease of use and setup.

πŸ’‘Program.cs

Program.cs is the main entry point for a .NET Core application. It contains the code that sets up the host and defines the startup process. In the script, Program.cs is used to automatically apply database migrations on application startup.

Highlights

Introduction to implementing services for data access using Entity Framework with Hot Chocolate GraphQL.

Installation of Hot Chocolate's data package to integrate with Entity Framework and handle parallel resolver execution.

Explanation of the necessity of the Hot Chocolate.data.entityframework package for parallel query execution.

Creation of DTOs (Data Transfer Objects) to reflect the GraphQL schema and describe database layout.

Demonstration of how to map GraphQL types to DTOs for Courses, Students, and Instructors.

Decision to move the Subject enum to a models layer for better separation of concerns.

Adjustment of the GraphQL schema to reference the moved Subject enum from the models layer.

Setup of the DbContext for the application, named SchoolDbContext, and its relation to the DTOs.

Configuration of the database connection string using appsettings.json and dependency injection.

Use of SQLite for simplicity in setting up the database and the installation of the necessary package.

Creation of database migrations using the .NET Entity Framework Core tools.

Correction of errors related to the Subject enum import and the necessity of the .NET Framework Design package.

Adjustment of the database schema to reflect many-to-many relationships between Courses and Students.

Removal and re-creation of database migrations to incorporate the many-to-many relationship.

Application of database migrations on startup through the Program.cs file for automated database setup.

Completion of the database setup and the generation of the school.db file.

Announcement of splitting the tutorial into two parts, focusing on GraphQL and Hot Chocolate in the next part.

Invitation for feedback, questions, and suggestions in the comments section for further engagement.

Transcripts

play00:00

now that we've covered all the graphql

play00:01

operations in our graphql api with hot

play00:04

chocolate we're going to move on to

play00:06

implementing services for data access so

play00:09

specifically we're going to have our

play00:11

services use entity framework to access

play00:13

a database and this is pretty much

play00:15

essential to most applications but this

play00:17

is also going to allow us to demonstrate

play00:20

more advanced hot chocolate graph heal

play00:22

features in the future such as data

play00:24

loaders pagination sorting filtering all

play00:27

that fun stuff so that being said first

play00:29

off we're going to install some packages

play00:31

so that we can integrate with entity

play00:32

framework so let's go to our project and

play00:35

manage nuget packages and we want hot

play00:37

chocolate.data.entity

play00:39

framework and the reason we want this

play00:41

instead of just regular entity framework

play00:43

by itself is because hot chocolate will

play00:45

actually execute some resolvers in

play00:47

parallel and by default any framework is

play00:49

going to freak out if you try and

play00:51

execute multiple operations at once so

play00:54

this package will take care of that so

play00:55

that we can execute those queries in

play00:58

parallel so let's install that so as

play00:59

always with nad framework we're going to

play01:01

have to create our db context and also

play01:03

our dtos that are going to describe how

play01:06

our data is going to be laid out in our

play01:08

database so let's come over to our

play01:10

project let's create a new folder let's

play01:12

have

play01:13

dtos and let's have services as well and

play01:17

in services i'm going to have my db

play01:19

context so let's create that i feel like

play01:22

our application needs a name but i'm

play01:23

just going to call this school

play01:25

db context so create that and we'll also

play01:28

create our dtos while we're here so as

play01:30

expected this is going to kind of

play01:32

reflect our graphql schema where we're

play01:34

going to have a course dto

play01:37

as well as a student dto and lastly

play01:40

we'll also have m instructor dto so as i

play01:45

mentioned this is going to reflect our

play01:46

schema so i'm going to bring that up

play01:48

just for reference i believe we have

play01:50

this in our queries we have our course

play01:52

type so for now on this course type i'm

play01:54

just going to grab all of these

play01:55

properties and move those over to our

play01:58

dto and just change them from here so we

play02:00

are still going to have an id and a name

play02:02

we are going to have a subject i'm going

play02:04

to come back to this but let's get rid

play02:06

of this

play02:06

hot chocolate attribute we have here we

play02:09

don't need that for instructor we're

play02:10

going to point to our instructor dto and

play02:13

for our students we're going to point to

play02:14

our student dto let's also have a

play02:17

foreign key property for this instructor

play02:20

so that's going to be a good and we'll

play02:22

call this instructor id by convention so

play02:25

now all we have left is subject so we

play02:27

could just import this from our graphql

play02:30

schema but i feel like our dtos should

play02:32

not reference our schema so we could

play02:34

just redefine a different subject enum

play02:37

here

play02:38

but i feel like what i'm gonna do

play02:39

instead is just move the subject enum

play02:42

into a layer that's kind of in between

play02:45

our dtos and our graphql schema which

play02:48

might not be the cleanest approach like

play02:50

maybe it would be a good idea to

play02:52

have your subject enum also in your

play02:54

dto's layer but instead i'm going to

play02:56

have a models folder here and we're

play02:59

going to add a new item here we'll call

play03:01

this subject it's not going to be a

play03:03

class just going to be that enum and

play03:05

let's just

play03:06

move that all in here so cut it out

play03:08

paste it in here delete it from our

play03:10

course type

play03:13

and now i'm going to import that in our

play03:15

schema i believe other places in our

play03:17

schema actually referenced that subject

play03:19

so i'm kind of happy about this because

play03:21

we had our mutations namespace

play03:23

referencing our queries namespace which

play03:25

felt off so now we've kind of moved

play03:27

everything to a centralized location in

play03:30

our model but that should be everything

play03:32

that needs to be updated in our schema

play03:34

let's head on back to our course dto

play03:37

import subject from our centralized

play03:40

models namespace now let's move on to

play03:42

instructor id so i'm going to open up my

play03:45

instructor type on my graphql schema and

play03:48

just grab all of these properties and in

play03:50

fact i don't think any of these are

play03:51

going to be different so we got our

play03:52

primary key and then just all the

play03:54

regular scalar properties so that should

play03:56

be all good and then lastly we have our

play03:59

student dto gonna head into my student

play04:01

type and this should be

play04:03

pretty much the same as instructor went

play04:05

where we can just

play04:06

paste all of that in here

play04:08

get rid of our hot chocolate attributes

play04:10

definitely don't want those here and

play04:11

that should be good to go so now that we

play04:13

have all of our dtos defined let's head

play04:15

back to our db context and define db

play04:18

sets for each of those dtos so our db

play04:22

context knows that we want a table for

play04:24

each of those objects so we're going to

play04:26

have a db set import that from entity

play04:29

framework

play04:30

for our course dto import that from our

play04:33

dto's namespace and this will be the

play04:35

courses and then we're gonna have two

play04:37

more db sets one for instructor dto

play04:40

these will be our instructors and then

play04:42

student dto these will be our students

play04:45

so now that our db context is ready we

play04:48

can register that in our services

play04:50

so we're going to take our services and

play04:52

we're going to add a pooled db context

play04:54

factory so let's specify our db context

play04:57

type the school

play04:59

db context and now we just need to

play05:01

configure it so i am just going to use

play05:03

sql lite here because in my opinion

play05:06

that's the easiest to set up but we are

play05:08

going to need a package for that so

play05:10

let's just search for sqlite and we

play05:12

actually want

play05:15

microsoft.netframerecord.sqlite so let's

play05:16

install that and now we can use sqlite

play05:20

so there we go import that from

play05:22

microsoft.net framework and now our

play05:24

connection string let's actually load

play05:26

that from our appsettings.json

play05:28

so we're going to have a variable for

play05:30

that here and we're going to have to get

play05:31

that from our configuration which

play05:34

isn't in our startup class so we're

play05:36

going to get that

play05:37

through the constructor so let's define

play05:39

a field for it this should be the i

play05:41

configuration so import that from

play05:43

microsoft.extensions and we should be

play05:46

able to get that through the constructor

play05:47

so let's generate that and our

play05:48

connection string is gonna be from that

play05:50

configuration so we can get connection

play05:52

string and we'll just call ours default

play05:55

so this is going to get loaded from our

play05:57

appsettings.json

play05:59

so let's head over to our app

play06:00

settings.json and we are going to have a

play06:03

connection strings key right here

play06:06

and we're going to have default and

play06:08

typical sql like connection string we're

play06:09

going to have data source equals and

play06:11

then the name of our database we'll call

play06:13

this school.db

play06:15

so this should be all good here we're

play06:17

getting this error because

play06:19

our school db context does not inherit

play06:22

from db context as it should there we go

play06:24

error goes away and our db context

play06:27

definitely would not work if we didn't

play06:29

inherit from db context so that's a good

play06:31

fix right there so now next up as always

play06:33

with nad framework we are gonna have to

play06:35

create migrations for our database so

play06:37

let's open our api in a terminal and the

play06:40

command to create a migration i hope i

play06:42

remember this so it's dotnet ef

play06:45

migrations oh i was so close but i just

play06:48

looked at the documentation because i

play06:50

could just never remember this so we're

play06:51

gonna add a migration and we'll call

play06:54

this initial and we're actually gonna

play06:56

build air real quick and this is related

play06:58

to moving subject to the model's

play07:00

namespace so gotta import it here in our

play07:02

course type input as well there we go

play07:05

let's try migrations again and we messed

play07:07

it up again so our query type also needs

play07:10

to import subject that was a pretty big

play07:12

breaking change let's try again let me

play07:14

build first make sure it actually builds

play07:16

there we go successful so we should be

play07:18

able to actually add the freaking

play07:20

migration now oh and i forgot we need

play07:23

microsoft.netfromrecord.design as a

play07:25

package so let's install that real quick

play07:27

this is not going as expected but that's

play07:29

okay so let's search for that package

play07:32

and install that real quick and try

play07:34

again this is only the fourth time not

play07:35

too bad and hopefully last but not least

play07:37

we also have to add a constructor in our

play07:40

db context that accepts db context

play07:43

options so let's do that real quick so

play07:45

we can actually just generate that and

play07:47

we want these options to be for our

play07:49

school

play07:50

db context so we got the constructor

play07:52

let's try i think this is like the sixth

play07:54

time but we should get it here there we

play07:55

go we got our migrations so looking good

play07:58

got all of our tables in here and

play08:00

actually i think our relationships are

play08:01

kind of messed up so our students table

play08:04

is gonna have a course dto id

play08:07

but in reality our student

play08:09

should be capable of being in many

play08:11

courses so i think what we have to do on

play08:13

our student dto

play08:15

is to find another property here and

play08:17

this is going to be an i innumerable

play08:20

of course dtos and we'll call those

play08:22

courses and this will tell enemy

play08:25

framework that we want this many-to-many

play08:27

relationship between courses and

play08:29

students and i think i actually also

play08:32

want a navigation property on instructor

play08:34

dto just to describe that one instructor

play08:37

can have many courses so let's remove

play08:40

that old migration so dot net ef

play08:43

migrations remove so there we go

play08:45

successfully removed and let's add

play08:47

initial again and now this definitely

play08:49

worked this time because we have this

play08:50

join table for course dto to student dto

play08:54

which reflects the many to many

play08:56

relationship between courses and

play08:58

students so now we could apply our

play09:00

migrations from the terminal down here

play09:02

but i think what i want to do instead

play09:04

is automatically apply migrations on

play09:06

startup so let's actually go into our

play09:09

program.cs and this is where we can

play09:11

actually apply our migrations against

play09:13

our database so we're going to need our

play09:15

host and we get that back from this

play09:18

build method right here so we build our

play09:19

host using the host builder and

play09:21

eventually we are going to run our host

play09:24

but in between all this what we're going

play09:26

to do is take our host services and

play09:28

we're going to get a required service

play09:30

here so import that from microsoft

play09:32

extensions and we want our school db

play09:36

context and actually before i get too

play09:38

far in this i already know that our

play09:39

school db context is registered as

play09:42

scoped so first we are going to have to

play09:45

create a scope so we get back this i

play09:48

service scope which eventually is going

play09:50

to have to be disposed so let's wrap

play09:52

that into using and now we can take our

play09:54

scope

play09:55

and take our service provider and

play09:57

resolve not

play09:59

a straight up school db context and the

play10:01

reason we don't do that is because we

play10:03

registered a db context factory not the

play10:06

actual db context so we are going to get

play10:09

an idb context factory for our school db

play10:13

context so put that into a variable and

play10:15

now this is going to be in a using

play10:16

statement but we're going to get back

play10:18

our school db context and we'll take our

play10:20

context factory and create our db

play10:22

context and now all we have to do is

play10:25

take our context take our database and

play10:29

migrate and that'll apply our migrations

play10:31

on startup so let's go ahead and run

play10:33

this and see if our database gets

play10:35

generated so no errors we successfully

play10:37

started and if we look over here in our

play10:39

project we have our school.db

play10:42

so we finally got our database set up

play10:44

and i think i'm going to stop myself

play10:45

right here and actually split this

play10:47

episode into two parts so this part one

play10:50

was all about just setting up entity

play10:52

framework and getting our database set

play10:54

up which actually took longer than

play10:56

expected so this part was kind of like a

play10:58

prerequisite for the next part which is

play11:00

going to be fully focused on graphql and

play11:02

hot chocolate i suppose i could have

play11:04

just done all of this db setup offline

play11:06

but i want to be fully transparent in

play11:07

this series if you already have a

play11:09

database then hopefully you skip this

play11:11

video and are moving along to the next

play11:13

part so hopefully this was helpful for

play11:16

getting set up with any framework of

play11:17

course next time we're going to do much

play11:19

more fun things but if you have any

play11:20

questions criticisms or concerns be sure

play11:23

to leave them below in the comments

play11:24

section if you enjoyed the video or are

play11:26

enjoying the channel consider becoming a

play11:28

member other than that leave a like or

play11:30

subscribe for more thank you

Rate This
β˜…
β˜…
β˜…
β˜…
β˜…

5.0 / 5 (0 votes)

Related Tags
GraphQL APIHot ChocolateEntity FrameworkData AccessDatabase SetupDTOsAPI DevelopmentData LoadersPaginationFilteringSorting