>> Tune in to this
week's On Dot Net, where I have my good
friend Brice on, who's going to demystify entity framework core
migrations, so tune in.\ [MUSIC] >> Hey, everyone, I'm James
Montemagno and I'm back with another On.Net episode this time probably one of my favorite topics of all time
because I know nothing about it, which is all about database migrations
with entity framework core. I brought none other than my best friend in the entire
world, Brice Lambson. How's it going Brice? >> Howdy, it's surreal being here. I remember when this
show premiered in 2016, I've been a fan ever since.
I'm honored to be on. >> I'm super excited
because everyone on the EF core team is just like,
you got to have Brice on, you got to have Brice
on because I'm like, I don't know anything
about anything. You're on the EF core team, correct? >> Yes. >> Yes. How long was it? How long have you
been on the EF core team and what all do you do there? >> Oh, man. I've been on
there almost 12 years now and I've been working on migrations
almost since the beginning. I work on reverse engineering, I work on a lot of
cycle light stuff. Those are the things
I remember right now. >> What would you say, now, if
people are just turning in, they're like, I'm in database
migrations. I love that. What is the pitch for
EF Core in general? Why are people using the EF Core
and why is it so important? >> Yeah, EF Core is just
one of many options. Database migrations
have been around, specifically database
schema migrations in other word migrations
is very overloaded. We're talking here about
your database schema, which is all the
tables like columns, the foreign keys, all
that database stuff. Migrate data schema migrations is a pattern for really evolving that schema as
your application evolves, as the requirements change. You can think of it a lot
like version control, which is for your source code. You record what changes you make to your source code so you can share
those with other developers. Schema migrations are the steps to evolve your schema as
your application evolves. They definitely weren't
invented by EF, they existed long before. If you've ever used Ruby active
record had migrations before us. Even way back in the
day I remember manually writing little tiny bits of sequel and checking
them in the repository. That's the pattern, it's recording
the changes to the schema. >> I have a database,
I have a person, for example, and I
have a first name, last name and I deploy that
application and then I'm like, oh, I forgot to add a middle name. Is that the scenario that I need a migration or is it a
scenario where I'm like, oh, actually, I put it as a string, but it should really be
an integer or something. Are those both examples that
I just listed as migrations? >> Yeah, definitely. I think
there's two big use cases. One is for everyday development, just like virtual control. Like I'm working on a feature, my teammate's working
on a feature and we're both evolving the database
schema and I don't want him to break me while I'm trying to work on my feature and so it's
just everyone being on the same page in terms of their local database
that they're testing with. Then you also mentioned
deployment and that's another things like, oh, we need to ship Version 2, all the databases are
still in Version 1. How are we going to not delete all their data and yet
update their databases? Those are the two big scenarios. >> Got it. Now, how come it just doesn't magically happen for free? Because I come from the
mobile world where I use SQLite Dash Net and I'm just slang in Pogo
objects everywhere, adding stuff, removing stuff. It just does it
automatically, I think. How come that just can happen? >> Yeah. Frank Kruger is a ninja. SQLite Dash Net, it hides all those stuff from you. It's really good at
additive changes. In fact, it's so good you
don't even know it's doing it. You just hand it data and it says, oh, I need to put
this data somewhere. I'm going to create
a column for you. I'm going to create a table for you. Additive changes, you've
probably never even encountered those database
schema. It works. It gets a little tricky
when you want to split the name column into a
first name and a last name. That SQLite Dash Net will then create two new columns and
the old one is just there. Yeah, you need to grow up
into a migrations framework. If you're using SQLite Dash Net, there's a really great library
called Fluent Migrator, I think is what they
call it and same with Dapper, you're not using EF. You probably don't want to
use EF just for migrations. There's another library that
encapsulates this pattern of recording the steps to your database and you write
it all in C-sharp codes. You don't really need to know SQL. That's the real beauty of
a migrations framework. >> Got it. That's
super cool. I've been getting into the web world where EF Core seems like just the de facto as a donor developer
that I'm going to use, it's built into templates
and beautiful scaffolding. I think the very first
time I was going through an MS Learn
module in the Kamro, it was I'll create this
thing and run a migration. I was like I have no idea
what's happening right now. I clicked a button
and things happened. I was hoping that you could
demystify that in a logical step. I'm brand new, which I am, by the way, to this. What am I actually doing or what is happening and how does the
tooling going to help me? >> Yeah, before we get there. As with any tool, you need
to stop and ask yourself, is migrations even the
right tool for me? There's a lot of people who
really love writing SQL, they like to craft
their database by hand. They might have a SQL server
project and they add tables to it. It's the source of truth, if you will, for the model. Everything flows from the database. You want to add something
to the database, you go change the database and then it flows back into your application. The SQL server project tools have a really cool
thing called schema. Therefore, you model your
table and then you say, okay, I want to make these
changes to this database and it will go out and
make those changes. We like to call this a database first workflow on entity framework. If you love doing this, if this is how you work, migrations are for you. >> Okay. >> Continue writing your
little SQL scripts or using the database
project deploy tools. In fact, there's a really
cool project called DB app, which is associated with
Octopus deployment, you can use it outside of that. All it is is a little
console app that you add your SQL scripts to and then it can just apply
those to a database. It takes care of the
tedious part of running those one by one and making
sure they run in order. Yeah, that's the tool if
that's your workflow. >> Okay. >> Where migrations really shine is on the other
end of the spectrum, you want your code to
be the source of truth. You want to add a feature, the first place you think to go is go change my app code and change it there
and so we call this code first, although you don't have to
start with the code first, but we like to call this
code first because it's the code is the source of truth and then everything
flows from there, whether that's you change
your domain model in your application and then
you go write a migration or you have it generated
for you in the case of EF. That's the flow there. >> Got it. That makes a lot
of sense where it's like I see where you're coming
from is like, hey, this database is
controlling the scheme and that is the source
of truth or the code, like you said, code for database
first code first make sense. The code and that's what
I'm used to is like, here's my person in
class, here's the thing. I'm like, database, please be what I want you to be
basically instead of the vice versa which
is database you are this and my code will react to
that. Did I summarize that correct? >> Yeah, and if your database
is the source of truth, we have something called reverse
engineering or scaffolding. You would make those changes to
the database and then you just re scaffold your model and it would bring in all those changes for you. That's a tool for that. But if we want to look at what it looks like. >> Yeah, it's all right.
You want to bring up your monitor and we'll give
it a look. Cool, I see it. >> Here's my super
simple application. It's just a console
app. I'm not fancy. EF works anywhere, you can imagine
it works in.NET MAUI projects. You are an Android app and we
work on Blazor WebAssembly. If you want to write
a little SQL database on the client side of the browser, which is like mind
blowing, you can do that. As you mentioned, it's
very popular with server side applications
if you have a web API. A lot of times you go through. Just a console out today just to
keep things simple for this demo. >> Okay. >> Here I have a blog
context and this is the EF's entry point into
the database and then on it. Right here is just an if statement, if I don't have any posts, add some sample ones just for the sake of having
it in our database, and then go through every post in the database and
just write them out. >> Looks super duper simple. That blog context, that is, something that's important. >> Yeah. Let's have a look at that. >> Okay. >> I have it over here in my model. It is just a class
that inherits from the DB context and this is
just entity framework magic. You don't really need to
know what it even does. Then you have these things
called DB sets and these map, one to one to a table. >> Okay. >> Gross table. >> DB set is like a table
and then that table is going to have columns with
different items in it, basically, like what is
a post? Is that correct? >> Yeah, and if you've ever heard
the term like a unit of work, I'm creating a new blog
context is like saying, I'm starting a unit of work. I'm going to make some
changes to the database or I'm going to get some
stuff out of the database. You create a new one of
these to go back to program, you create a new one of these, make the changes, and then commit that unit of works persist
everything to the database. >> Is that what we would call a transaction basically at that point? >> Yeah, every time you
call save changes there, it wraps all these
changes right here. It's adding three rows to the
database in a single transaction. If it fails, you end up
somewhere in the middle. >> See, I know a little
bit of the lingo, but yes, Frank has hidden
most of it from me. I get it. Perfect. >> Then just in here,
I'm using SQL lite. EF call works with all
databases, PostgreSQL, we work with MySQL, SQL Server obviously, Azure SQL, you name it. There's lots of providers. I
like SQL 8 because it's simple. Here I'm just writing to
a file called Blogs.db. Then here I have my plain old sale, or object, my pocker for my model. This could flow all the
way into your views if you are writing like
a client side up. Here's a post it has an ID. Lots of database is just use surrogate primary keys they
call them just to keep track. Because there's no such
thing as like an instance. You can't just take an instance out of the database
and shove it in a C-sharp, this identifies this piece of data and it has a title and it
has some content. Super simple. >> Nice. >> I've got my app written, my super cool app. I'm ready to run it. Let's
see what that looks like. >> At this point, you
haven't really done any these usual code basically. >> Yeah. This is all just plain old. Immediately I had an error. >> Oh my goodness. It's ah. But what's going on because
I thought you are all about, EF on the EF team, how could this happen. >> It says there's
no such table posts. I don't have a database. I never created the database. I wrote on my code
and I went to query it and it threw it because
it couldn't find any data. I couldn't even find the database. Let's look at what it looks like
to actually create the database. The first step is to
create a new migration. For this we use the NuGet
package manager console. Is a little tool here, and
this is an odd little thing. You can think of it
as like a console that knows more about Visual Studio. You can actually use those
to install packages. The first step, when you
want to get started, you need to install the tools. >> You're bump that up for me
on that little 100 down there. >> It works. >> Yeah keep it going
a little bit more. >> Here we go. >> Perfect. >> It's really big. I'm going to use this to install
the tools as an airbag. You could also right-click on your Solution of
managing the packages. I just put it in the console
here to get used to it, because you're going to
see it here in a minute when we start using migrations. >> I need this, so even though it's just like initializing the database, I'm still creating a migration
that gets an initial migration. >> Yeah, your very first migration is going to go from
nothing to something. You're going to create
the schema as it is right now in your account. >> Got it, I think that was always
my confusion because I'm like, I'm not really migrating
anything, but that makes sense. You are migrating from you had
nothing to this is the thing that you want in v1. V0 to v1. >> I'm going to install
this tools package. All it does is just add a
package to my CS project. Well, that's really big. I think those are linked together. I'm not going to zoom out yet, so
I'm going to keep working here. >> Okay. >> Now I have these
tools installed and they add a few commands you
don't have to use. This is the Visual
Studio way of doing it. There's another way
if you're working in like Visual Studio or
outside of Visual Studio, like Visual Studio from Mac or
of your code or if you like, Emacs or VM or whatever. You can do all this
stuff on the console and the way you do that is just
go in that tool install. I like to install it globally, so that's available everywhere. It's just a tool called.Net EF. >> Cool. >> This is the command line way. If you're a console junkie and
you like black and colorful text. Then it has similar commands to what you're going
to see in a minute. You just invoke it with.NET EF. You get to see this
cool little unicorn. >> You can't be [inaudible]
I mean, come on. >> For sure. I
actually created that. I put it in as a joke with the team. Let me keep it, so I was excited. It has migrations, commands. It has commands for working with
the database or the data context. This is a command-line
way of doing it. I'm not going to show that because
I like using Visual Studio. I like to stay in Visual Studio. There's PowerShell command
for the same thing. Right now we're going
to add a migration. We're going to just
call it InitialCreate. Now, this is like a get
republic or I have like my first command where
I add all my code. I'm going to add all my schema as it is now so I can start evolving it. >> Is that initial create, is that just a tag that you set or is that actually a keyword
that's of importance? >> This is the name
of the migration. You can think of it as
like a commit message, and the way it comes out is it actually becomes the
class name here. >> Interesting. I'm not going to spoil it, you're
going to do much cool stuff. I'm not going to stop [inaudible]. >> Yeah, you see over here, by default, it creates
a migrations folder. Then you can see the
initial create there, and it puts this big old
time stamp in there. The reason it uses the time stamp is to help keep everything
ordered correctly, because at the end
of the day, they're just files on the file system. But if you can see
like the sequence of changes and if your team's working on something else and
you merge in their changes, you see when they made their change. >> Got it. That makes sense. >> Let's look at the
anatomy of a migration. You get this class that has an up
method and it has a down method. The up methods bring
the database up to date with this migration where your
model was at, in this migration. It has this funny little DSL, looks like SQL, but it's very C Sharp as well. We're going to create a table, so the post table has an Id, has a Title, has Content, it's got a PrimaryKey,
that Id column. One thing here, though the title here says that
it's knowable true. That was like a mistake, like, oops, I'm not ready to share
this with the team. I'll show you in a minute.
We're going to get to that. Let me finish going
through the anatomy. >> Okay, got you. >> I getting ahead of
myself, so excited. All right, the down method obviously if you
unapply this database, you go back to nothing and so we
drop the only table we created. >> A drop is like a deletion? >> Yeah. It'll delete the table and all of its data from
the schema in the database. >> These are just helper methods, no one's calling this yet. These are methods
that you could call. I guess you could new up an initial create and
then call those methods. >> Interesting point. When this
method right here is called, it doesn't actually create a table. This tells EF to generate SQL
in order to create a table. That is a very
important distinction. This is defining the script. This isn't actually just finding like execute this code procedurally. It's a little language that EF
uses to represent a migration. It's abstracted away from
the specific database. Like you can see traces of, oh you're using SQLite, we're going to throw in
an Autoincrement there. But in general like whether
you're using MySQL, PostgreSQL server, all the migrations
use the same language here. >> Got it. Cool that makes sense. It knew that the idea to autoincrement that was
the thing, just EF magic? >> Pure EF magic, yeah. You can type every little thing
about your model saying this is the primary key and I want
to use this database type. EF has just a ton of conventions. By default, it will look for an integer or I don't even
think I was doing integer. It just has to be a column named Id, and that will be your primary key. So if I wanted to call that key, suddenly EF wouldn't know what the primary key was and you'd
have to go and tell it. >> Got it. >> We call it convention
over configuration. You don't want to go
configure everything, so we have these
conventions and if you follow them you can write less code. If you don't follow
them, you can tell us what we don't know,
tell EF how to do it. >> Cool. >> Back to the anatomy
of a migration. Underneath this little initial
create with the up and down, there's this designer file. Peel back the curtain and look
behind and see what's here. You don't really need
to know about this. All of this is a snapshot of your model and it's
almost never used. It's just here in case
when we're generating that SQL we need additional
information and a look here. One cool example is on SQLite. You can't actually alter a
column, they don't support that. One of the things
we have to do is we have to rebuild the entire table, like recreate it in a new place, copy all the data
over and delete it. All just for a little alter column. The alter column clearly isn't
enough to do all of that, so we'll actually peek
back here and say, okay, when we recreate this table, it's going to need all this
additional information. This is like a last resort though. >> Got you. >> Because we can, we use
the stuff that's right here. >> Okay, cool. It's
cool that it's there. >> Yeah. Good to know it's
there. Don't delete it. It might be used. The other thing we get as a model snapshot and
it's exactly the same thing. It is another snapshot of your
model at this point in time. This one has a very
different purpose. This is so that the next
time you call on migration, we know where we're coming from. Because if you're just
changing your apps model like we don't know. All we have is an
up and down method. This tells us create an
up and down method for the changes between the snapshot and then when you
generate a new migration, this snapshot will
be overwritten with the next current model on
the next current model. >> Got it. What you're saying is like this is the
current snapshot in time and then the migrations would build up all the
changes that you made do it. >> Yeah. >> Okay. >> All right, so that's the
anatomy of a migration. Like I said, I don't like that you can add a post without a title. That
doesn't feel right to me. I want to go back and I
want to make that required. The good news is I haven't shared
this migration with anyone, so I can just go and actually
delete all this stuff. But again like if you've added
two migrations you don't want to just delete the snapshot because
that it will be completely lost. >> Got it. >> There's another command to
sort of keep all this stuff in sync and it's removed migration. >> This is kind of you're playing around with it. You're a developer. You think that you did it but
actually you didn't do it. You're like I messed up, rollback. I don't want to go into Git and undo everything because
you don't want to mess up all your code
changes basically. >> Yeah. I really like thinking about version
control in this context. Like, oh I thought I was ready to commit my changes and
push and send a PR. Whoops, I'm not quite ready, so let me go back and sort of amend that last
commit and Git lingo. >> Got it. >> I'm going to undo this migration. I want to take this one away. I'm not ready to share
this with anyone. It's not in the way I want it to be. Remove migration just sort of
removes the last migration. >> Okay, just like the
last one in general? >> Yeah. While keeping the snapshot in sync and
everything like that. Of course it was my first
one, so I just deleted it. All right, let's go and make
that column actually required. I'm just going to
use data annotations here because they're
simple to understand. >> This is part of EF Core or? >> Yeah, this is part of EF Core. There's two ways to do things. One is with these annotations, the other is to override
on model creating. It's a lot more code but some
people really prefer that. Then you could say
modelBuilder.entity Post. This property, oops I
forgot my parenthesis. The Property Post. You can see it's a lot more code. >> Yeah. >> The dot is required. >> Oh, wow. Okay. >> If you really want to
write it this way you can. One of the reasons people don't like these annotations is that
they pollute your POCOs. It's not really a POCO anymore. It knows more about
how it's resisted. I think required doesn't
really fit that definition because your UI layer might
use this for validation. >> Yeah, sure. >> It's just a flavor. There is no right or wrong way. We just allow different
ways of doing things. >> Yeah. I've definitely
seen people that I really, really want my model to be in a completely separate library and it should do
nothing about anything. That's cool that there
are those two options. >> Yeah. Let's look
at that one again. All right, and now we can see that the title column is not nullable. You must specify one of these. >> Got you. You needed
to do it there. You couldn't just go on and change. You should really never
change these files basically. You shouldn't touch them. >> I wouldn't say that.
You may want to change these but don't change them in a way that is out of sync with
your entity framework model. You could say now it's required
in my domain model but actually, I want to allow some
bad data in there. You want to relax some constraints. My application should never
insert this data but if some bulk update happens to import data without null then
maybe it does. I don't know. But yeah, in general you probably
don't want to edit these. You may want to tweak
them a little bit. But not in the way that disagrees with what you already
wrote in your classes. That's kind of the definition of
insanity. Your model is not sane. >> Got you. Cool. >> Now I have this migration. It's the way I want it to be. I'm going to go ahead and
actually create my database now. I'm going to apply this
migration to the database. There's a simple command
called Update Database. If I do dash verbose, we're going to see a bit more
output here just so you can go wow. You can see a bit more
of what's going on here. >> This is like creating
it on your local machine? >> Yeah, it's creating it actually
right here in my directory. In fact, let's look
at the database here. Here I'm using the SQLite toolbox by Erik Jensen, a good
friend of the EF team. It's just a simple way of
inspecting SQLite databases. Here's the post table created
an ID with a primary key. It's got a title
column, not nullable. It's got a content. In here
there's this other little table. It has double
underscore, so you know it's special, don't touch it. >> Yeah, that's super special. Not just one underscore
but two underscores. >> Two underscores, yeah. This is how EF keep track of which migrations have been
applied to the database. Again, like you're working in
a team environment, you pull. You need to apply your teammates
migrations to your database, needs to keep track of which ones. If we actually look at this data, you can just see there's that
initial create, it's been applied. >> Oh, cool. >> You can even keep
track of what version you used to apply it. Just for fun. >> Nice. >> Now when we run our app
everything should work because we have a
database, has a schema. We can actually put data in the database.
Let's go ahead and run it. >> Got it. There's nothing
that you need to do. You don't need to call the migration in code because
you've executed it here, so your database is up
to date with the schema. It's executed the SQL commands
to generate the tables. >> Oh yeah. Let's go back
to that verbose output. See right here, you can
see the create table post. That update database command, what it does, is it
looks for the database. If it's not there, it will
create the database if it can. It will see which migrations
have been applied. It will generate the scripts
for those migrations, the scripts being this
create table right here and then run those
against the database. >> Got it. >> This is very much like
a developer time thing here, like a gesture. We'll look at other ways of
getting migrations applied. Let's run our app and see
if it actually works now. Did that work? Did it already run? >> It already run. >> Let's delete that database. Let's try all that
again. It shouldn't actually have data in there. I'm surprised. Maybe
I kept one around on accident. Update database.
Now we run. There you go. Adding sample data, and now I was supposed to run it and it doesn't
add the sample data, there we go the second
time I "run" it, I doesn't have the
data enlisted there. Let's look at making another
change to the database here. For this one, let's add an author, so each blog post should
have an author here. Now I've just changed my application code and that's enough for any
framework to know what to do. Let's add another migration. >> Okay. >> We'll just call it AddPostAuthor. Something descriptive to help
me know what's going on here. >> I saw that it autosave
the file for you. >> Yes, that's really
the beauty of using the package manager console commands as opposed to the
command line interface, but it doesn't know anything
about Visual Studio. >> Got it. >> You'll also notice it
will pop up the file. Is that little, little
things like that, that make it more integrated, which is why I still prefer it. Here we go. We're just
going to add a Column, an Author Column to the Posts table and it's
text, and on a level. >> Yeah, and I see you've
just added it right below it, so the very first one and
then it just goes down below. Because date, times
stands basically. >> Yeah, definitely. Again, I haven't applied
this to my database, so let's do that.
Let's update database. It will look in the
database, and say okay, I only need to apply
this AddPostAuthor, migration has already been applied. Then if I refresh the
database over here, it should have that author column. I expand everything
again. There it is. >> How cool. >> Though that's not a
super simple overview of the workflow of using migrations. Another interesting thing, now that I've applied this, if I actually try to remove it, it will warn you and say, you've already applied
this to the database. You need to think about
this a little more. because if have you share
this with your teammates, it's like rewriting Git history. If you do a forced push, everyone's machine is
going to be out of sync and it's going to be
very hard to get it back. Before you just reverb and
change your migration, you need to stop and think about, how does this migration then
apply to other databases. If it has, don't remove it, just add another migration on top of it so that everyone
can keep rolling forward. >> Got it, so in that case, would you then remove
the author from your code and then run
another migration? Then actually it would disappear. It would be like create it, add it, remove it. But then everyone's in
sync, so it's okay? >> Yeah, definitely. >> Interesting, okay. >> Again, I have that
version control mentality. This is very key to me here. I think it really helps you
use Migrations correctly. >> Now I have a question for you and maybe I'm
jumping the gun here, but you have a database that's
here in your source code, right, that you would check in magically
and to get or not in to get, maybe you would ignore that,
so everyone's running it. What if that database
doesn't exists on a server. How does it know when you start
up your app that you need to run Migrations or do I need a VPN into a machine and run these
commands in prod? >> Yeah, and the
answer is it depends. Think about node development. There are thousands of
databases on everyone's phone. You can't just VPN and run.
You can't just change that. I hope you can't anyway
that would be a total loss. You can't just change
their databases. It needs to be part of
an upgrade experience. Like, they've downloaded
Version two of my app, their database is
still at Version one. You need to roll it forward, and so in that case, where there's, a phone accessing a local database, it's absolutely safe to write here during app start to
apply the Migrations, db.database.Migrate [inaudible]
how you using here. There we go. This does basically the same
thing as our update database, and only when your app is running
it will find the local database. It will see which migrations
need to be applied. If the database isn't there, it will create the database. This is super handy for
client development. But if you think about
this on a server where you're scale out to 10 nodes, all accessing the same database, they're going to be stepping
over each other's feet. It's going to be a nightmare, and so we really don't
recommend this on a server scenario unless you have a single server accessing
a single database. >> Got it. That makes sense. >> [inaudible]. >> Yeah. >> When you are in
that server scenario, the one where we do recommend it, is the traditional way you generate a sequel script and there's
a command for that too. It's just called script-migration. >> Okay. >> This is like an artifact
that you can then go and hand Your DBAs who know
everything about databases, they can review it, they can say, "Well
actually you need an index here, when you
create this table." They can review it. This can become part of your deployment process. >> Got it. That's really
good, it's really nifty. There's all of these
different commands built in, including, here's the sequel
script. That's really cool. >> Yep. >> Nice. Anything else you want
to demo through or it's covered? >> No, I could go on
forever about this stuff, but I don't want to
overload viewers. This is merely an introduction to
how do I start using migrations? >> I think this is great
because I honestly, I feel like sometimes I can
walk through the tutorial, but I'm not actually
getting the sense of exactly why or where all
these files are out. To me, this is actually perfect. On that note episode I'm going to rewatch probably like 100
times is that every time I create a new EF Code database and I'm using anything, I'm
going to go through all that. Brice this is absolutely perfect
in every regard. I love it. >> I'm glad, and if
you want to know more, are the docs, the docs.Microsoft/ef. There's all kinds of great
docs in there about, Well I want to use SQL Server
and SQL items in my application or what are some other tips you
have for team environments? We have these things called
bundles. What's a bundle? They were new in the episode. All kinds of more information, if you go and look at the docs. >> That's awesome and
we will put links down in the show notes below regardless of where you're
at or if you're on Docs right now or you're on
YouTube, go down there. I'm going to get all
those cool fancy extensions that Brice had as well, so everyone can install those. You're using Visual
Studio and of course, also the Command-line stuff too. Brice, thank you so much for coming
on and walking through this. This is absolutely delightful. >> Yeah, my pleasure. >> Awesome. Thanks,
everyone, for tuning in. If you have any questions at all
about anything but specifically, probably EF Core and
Database Migrations, leave them in the comments below. If you're over on
YouTube, I have Brice, go and check those
out and comment back as well and I'll check on them too. If you're over on YouTube,
don't forget to like this video and ring
that notification bell. Hit subscribe so you get notified whenever we put out new
YouTube videos here. Brice, thanks again for coming on. Thanks everyone for tuning
in and have a great day. [MUSIC]