WEBVTT

00:00.020 --> 00:02.870
Okay, so now we've got our entity in place.

00:02.870 --> 00:05.270
Let's go to our store context.

00:05.300 --> 00:11.240
Next as we're going to update our Dbcontext class.

00:11.270 --> 00:16.430
Now we're going to add another DB set I'll say prop DB sets.

00:16.430 --> 00:19.190
And this one's going to be for the baskets.

00:19.610 --> 00:24.200
And we'll specify baskets inside here.

00:24.200 --> 00:27.140
And once again I'm just going to make this required.

00:27.530 --> 00:33.080
Now we don't need to add a DB set for basket items.

00:33.080 --> 00:37.310
Even though this is going to be a table in our database.

00:37.310 --> 00:45.470
Because we've got the relation inside here from the baskets to the basket item, then Entity Framework

00:45.470 --> 00:52.070
by convention will create the table for this, but it might not create it quite how we want it, because

00:52.070 --> 00:57.620
in the store context we're going to have based on conventions, because we've got a DB set in here called

00:57.650 --> 00:58.310
baskets.

00:58.310 --> 01:03.590
This is going to be the name of the table and also based on convention, how we've laid out the code

01:03.590 --> 01:08.570
in our basket with the navigation property to the items here.

01:08.570 --> 01:13.790
Then this is going to set up the foreign key relationship between the basket and the items.

01:13.790 --> 01:18.230
For a one to many relationship, one basket can have many items.

01:18.530 --> 01:23.810
Also from our basket item because we've got the navigation property in here for the product, then it's

01:23.810 --> 01:28.220
also going to set up the relationship between the basket item and the product.

01:28.250 --> 01:30.380
It may not be exactly how we want it though.

01:30.380 --> 01:38.420
So typically at this point we would create a new migration and see what Entity Framework managed to

01:38.450 --> 01:41.090
configure for us based on conventions.

01:41.090 --> 01:46.340
And then if we need to tweak it, we can remove that migration, come back, make some tweaks and then

01:46.340 --> 01:47.660
create another new migration.

01:47.660 --> 01:51.830
That's the approach I just want to demonstrate now, as when you do create a new migration, you're

01:51.830 --> 01:52.760
not stuck with it.

01:52.760 --> 01:57.770
You can remove it and make tweaks, then create another migration or replace that migration, I should

01:57.770 --> 02:04.160
say, with an updated version, check that one and then go through that same process again if you need

02:04.160 --> 02:04.580
to.

02:04.610 --> 02:10.010
So let's open up the terminal and we'll go to the terminal where we're running our API server.

02:10.010 --> 02:14.960
Now it tells us that we need to restart our API, but I'm actually going to stop it at this point,

02:15.470 --> 02:22.430
as when we do mess around with migrations and database functionality, we do need to stop our API server

02:22.700 --> 02:26.990
because it builds and compiles our code when we use these commands.

02:26.990 --> 02:36.170
So inside the API folder I'm just going to say dotnet f migrations at and say basket entity added.

02:37.520 --> 02:42.440
And we don't need to specify an output directory because we've already got a migration in there.

02:42.440 --> 02:44.840
So it's going to be located in the same folder.

02:44.840 --> 02:48.740
So I'll press return and see what happens.

02:48.740 --> 02:50.720
And that was successful.

02:50.720 --> 02:53.630
So let's go take a look and see what that did give us.

02:53.630 --> 03:00.560
So inside the data migrations folder we've now got a new migration for basket entity added.

03:00.590 --> 03:03.350
And let's take a look at the highlights inside here.

03:03.350 --> 03:05.640
So we're creating a table called baskets.

03:05.670 --> 03:06.300
Perfect.

03:06.300 --> 03:13.410
That's what we want inside here we've got an ID column that's going to be SQLite Autoincrement ID and

03:13.410 --> 03:16.590
we've got our basket ID column which is going to be a string.

03:16.590 --> 03:18.300
And it's not allowed to be nullable.

03:18.300 --> 03:19.980
We have to provide that.

03:20.130 --> 03:25.110
And we've got our primary key which is set to our ID of the basket.

03:25.170 --> 03:29.910
Now in the second one we've got another create table, but it's called basket item.

03:29.910 --> 03:35.910
And that does not make me happy because I like tables in the database.

03:35.910 --> 03:39.840
Even though I barely look at the database I still want them to be pluralized.

03:39.900 --> 03:45.720
No good reason for that, but that is kind of conventional to pluralize table names, so I would like

03:45.720 --> 03:47.100
that to be pluralized.

03:47.130 --> 03:49.590
Now please don't be tempted to do this.

03:49.590 --> 03:55.110
And and the name you want in manually that will work.

03:55.110 --> 03:57.000
That will name the table correctly.

03:57.000 --> 04:04.230
But if you remove a migration and add it back in, you're manually edited, change is not going to persist.

04:04.230 --> 04:10.300
So really you want to create your migrations from your code without making any manual adjustments inside

04:10.300 --> 04:10.810
here.

04:10.840 --> 04:14.530
Even though technically you can get away with it.

04:14.530 --> 04:17.320
And let's see what else we've got inside here as well.

04:17.320 --> 04:22.150
So we've got our basket item, then we've got the basket item ID, the quantity and the product ID.

04:22.180 --> 04:22.930
All good.

04:22.930 --> 04:26.290
But we've got another issue here that doesn't make me happy.

04:26.290 --> 04:28.960
The basket ID could be nullable.

04:28.990 --> 04:31.030
Now is that a problem?

04:31.630 --> 04:35.200
Do we want basket items without a corresponding basket?

04:35.200 --> 04:37.990
Because that's what we have potential to do there.

04:37.990 --> 04:39.220
I'm going to say no.

04:39.250 --> 04:43.900
I want every basket item to be associated with a basket.

04:44.050 --> 04:46.870
And that's going to have a further impact down here as well.

04:46.900 --> 04:54.220
Because what we have is the relationship being set up between our basket item and both the basket and

04:54.220 --> 04:55.420
the products tables.

04:55.420 --> 05:02.620
Now, inside the products relationship between the basket item and the products, we have a delete behavior.

05:02.650 --> 05:08.010
What's going to happen if I delete a product from the products table.

05:08.040 --> 05:15.570
Then that's going to cascade into the basket items and remove that item from any baskets where that

05:15.570 --> 05:17.700
product was being used.

05:17.700 --> 05:22.230
But we do not have a similar action for the basket items.

05:22.230 --> 05:27.930
So that means we could delete a basket, but we would not necessarily delete the basket item.

05:28.650 --> 05:32.490
So again, something I'm not quite happy about there either.

05:32.520 --> 05:37.140
And what we also have is indexes being created as well.

05:37.170 --> 05:37.680
Great.

05:37.710 --> 05:42.510
Okay so we've got a couple of tweaks I would like to make inside here because I'm fussy about the table

05:42.540 --> 05:51.690
names, and I don't like the idea of the potential to have orphaned basket items in our database.

05:51.870 --> 05:58.440
So we have numerous different ways of configuring this, and my preference most of the time is to stick

05:58.440 --> 06:02.430
with conventions where possible and attributes where possible.

06:02.430 --> 06:05.820
But we can come in and also configure our store context.

06:05.850 --> 06:08.220
We could override what's going on in here.

06:08.220 --> 06:15.960
What we could do is if I specified override and press space, then one of the methods inside here is

06:15.960 --> 06:17.610
the on model creating.

06:17.610 --> 06:21.330
And what we could do is configure our entities using this approach.

06:21.330 --> 06:22.350
I'm not going to do that for now.

06:22.350 --> 06:26.130
We'll take a look at that maybe a bit later on if we need to.

06:26.130 --> 06:30.180
And the approach I'm going to take a look at is using conventions.

06:30.180 --> 06:35.970
So for the basket item I don't like the table name just being basket item.

06:35.970 --> 06:42.810
So what we can do here is we can specify table and use a data annotation attribute.

06:42.810 --> 06:45.720
And then we can give the table a name.

06:45.720 --> 06:48.600
And I'm going to call this table basket items.

06:48.600 --> 06:53.970
Doesn't make any difference to how we access this in code, but it will affect how it's displayed in

06:53.970 --> 06:56.070
the database for the table name.

06:56.250 --> 06:59.040
That's one thing I wanted to adjust.

06:59.070 --> 07:07.170
The other thing was to deal with the fact that we've got the potential to have a basket item that's

07:07.170 --> 07:08.970
not associated with the basket.

07:08.970 --> 07:10.770
We don't want that behavior either.

07:10.800 --> 07:17.130
Now, the way we do this in conventions, if we come to our basket item, then we can what's referred

07:17.130 --> 07:20.640
to as fully defined relationship with our entity.

07:20.670 --> 07:24.870
Now in the basket, we've defined the basket item inside here.

07:24.870 --> 07:31.770
And to fully define this relationship we add the equivalent navigation property inside this class as

07:31.770 --> 07:32.430
well.

07:32.430 --> 07:39.180
So as well as the product ID we're going to have a prop that's an int for the basket ID.

07:39.180 --> 07:44.100
And we're also going to have a prop for the basket and call it basket.

07:44.100 --> 07:46.950
And we'll also make this required.

07:48.000 --> 07:51.120
And I didn't get any problems creating the migration with this required.

07:51.120 --> 07:51.960
So that's good.

07:51.960 --> 07:56.280
We don't need to make this nullable or initialize it to null inside.

07:56.280 --> 07:57.840
Here we can use this required modifier.

07:57.840 --> 07:58.950
We never used to be able to do that.

07:58.950 --> 07:59.520
By the way.

07:59.520 --> 08:04.080
That does seem to be something they've fixed I guess in dotnet nine.

08:04.080 --> 08:07.020
And let's go back to our terminal.

08:07.020 --> 08:09.780
And I want to remove this migration.

08:09.780 --> 08:16.380
So we'll use the command dotnet f migrations.

08:16.380 --> 08:19.080
Remove and press return.

08:19.110 --> 08:25.260
By the way, this command will only work if you have not already applied this to your database.

08:25.260 --> 08:27.060
So I've got my API server stopped.

08:27.060 --> 08:32.040
So there's no way that this previous migration or this migration here has been applied to the database.

08:32.040 --> 08:33.030
So I'll press return.

08:33.030 --> 08:35.640
And this should be removed without issues.

08:35.640 --> 08:36.720
Or it would have been.

08:36.720 --> 08:41.670
But I've got a problem and it tells me that required member basket.

08:41.670 --> 08:47.520
Item basket must be set in the object initializer or attribute constructor.

08:47.550 --> 08:55.950
And that's the reason that I did want to not make this required, because we cannot create a new basket

08:55.950 --> 08:59.700
item without also specifying the basket inside here.

08:59.700 --> 09:05.160
So we would need to specify the basket ID at a minimum I think.

09:05.190 --> 09:06.570
Let's just add that in.

09:06.600 --> 09:09.000
No, we would actually need the basket entity in there.

09:09.000 --> 09:17.050
So that was the reason why I was thinking that the required property would not work for this, and indeed

09:17.050 --> 09:17.530
it doesn't.

09:17.530 --> 09:25.240
So what we do in this scenario is we don't supply the required property, but we do give this an initial

09:25.240 --> 09:30.310
value of null, which is not allowed because of the nullable reference type setting we've got.

09:30.310 --> 09:33.460
But we can override it with an exclamation mark.

09:33.460 --> 09:37.150
And that is the solution to lists.

09:37.150 --> 09:39.640
So now I've removed any errors from my code.

09:39.640 --> 09:45.010
I'll go back to the terminal and let's repeat that command to remove the migration.

09:45.010 --> 09:47.530
And that should work without issue.

09:47.530 --> 09:49.180
And sure enough it has.

09:49.180 --> 09:56.140
So let's clear the window and let's repeat the commands to add the migration for basket entity added.

09:57.280 --> 09:58.210
And great.

09:58.240 --> 09:59.680
Now that has been created.

09:59.680 --> 10:03.520
So let's go back to Solution Explorer and open up the migration.

10:03.520 --> 10:07.540
Make sure that the changes we wanted are in place.

10:07.540 --> 10:11.680
So I can see that the table name is called basket items.

10:11.680 --> 10:16.870
I can see that the basket ID is no longer allowed to be nullable.

10:16.870 --> 10:23.080
And what I've also got in here is the referential action cascade for the basket item, which means if

10:23.080 --> 10:30.160
we were to delete the basket, then that also ensures that any related basket items also get deleted.

10:30.190 --> 10:31.210
So great.

10:31.240 --> 10:35.890
Now we just need to make sure our application starts so that we can apply that new migration to our

10:35.890 --> 10:36.370
database.

10:36.400 --> 10:43.090
So I'm just going to execute dotnet watch, press return and make sure our application starts up cleanly.

10:43.090 --> 10:44.440
And indeed it does.

10:44.470 --> 10:48.640
And we can also go take a look at our database file.

10:48.640 --> 10:55.090
And if we click on store db what we should find is that we've now got a baskets table with the ID and

10:55.090 --> 10:55.900
basket ID.

10:55.900 --> 10:59.410
And we've also got the basket items table inside here.

10:59.410 --> 11:05.320
And we can see the foreign key relationships have been set up with that little white key here to say

11:05.320 --> 11:08.260
that these are the foreign key IDs.

11:08.260 --> 11:09.340
Perfect.

11:09.430 --> 11:11.410
So now we have that in place.

11:11.410 --> 11:15.850
What we'll take a look at next is creating a basket controller.
