Entity Framework Migrations Explained

dotnet
4 May 202236:52

Summary

TLDRIn this episode of On Dot Net, host James Montemagno is joined by Brice Lambson, a member of the Entity Framework (EF) Core team, to demystify EF Core migrations. Brice explains the concept of database schema migrations as a pattern for evolving the database schema alongside application development, akin to version control for source code. He covers the importance of migrations for both everyday development and deployment, illustrating the process with practical examples. The conversation guides viewers through the creation and management of migrations, emphasizing the need for caution when modifying applied migrations. The episode concludes with insights on applying migrations in different environments and the importance of aligning database changes with team workflows.

Takeaways

  • 😀 Entity Framework Core (EF Core) is a popular ORM (Object-Relational Mapper) for .NET applications that simplifies database interactions.
  • 🔄 EF Core migrations are used to evolve the database schema as the application evolves, similar to how version control manages source code changes.
  • 🛠 There are two main workflows in EF Core: Database First, where the database is the source of truth, and Code First, where the application code is the source of truth.
  • 👥 Brice Lambson, a member of the EF Core team, emphasizes the importance of choosing the right workflow based on the team's preference and the nature of the project.
  • 🚀 Migrations are not just for new developments; they are also crucial for deployment, ensuring that databases are updated without data loss when a new version of an application is released.
  • 🔧 EF Core provides tools to scaffold or reverse engineer the model from an existing database, which is useful for Database First approaches.
  • 📝 The process of creating migrations involves generating an 'up' method to apply changes and a 'down' method to revert them, encapsulating the changes made to the database schema.
  • 👀 It's important to keep migrations in sync with the application's model to avoid conflicts and ensure a smooth deployment process.
  • 🛑 The 'remove migration' command in EF Core allows developers to undo the last migration, which is helpful for correcting mistakes before they are shared with the team.
  • 🔗 The 'Update Database' command applies pending migrations to the database, and it's commonly used during development to keep the local database up to date with the application's schema.
  • 🔗 For production environments or server scenarios, EF Core offers the 'script-migration' command to generate a SQL script that can be reviewed and applied by DBAs as part of the deployment process.

Q & A

  • What is the main topic discussed in the 'On Dot Net' episode with Brice Lambson?

    -The main topic discussed is Entity Framework Core migrations and how they can be used to manage database schema changes over time.

  • How long has Brice Lambson been working on the EF Core team?

    -Brice Lambson has been working on the EF Core team for almost 12 years.

  • What is the purpose of database schema migrations in the context of application development?

    -Database schema migrations are used to evolve the database schema as the application evolves and requirements change, similar to version control for source code.

  • Why are Entity Framework Core migrations considered important for application development?

    -EF Core migrations are important because they allow developers to manage and track changes to the database schema in a structured way, facilitating collaboration and deployment.

  • What is the difference between 'database first' and 'code first' workflows in EF Core?

    -In 'database first', the database is the source of truth and changes are made directly to the database which then flow back into the application model. In 'code first', the application code is the source of truth and changes are made to the code which then flow into the database through migrations.

  • Why might a developer choose to use 'database first' approach instead of migrations?

    -A developer might choose 'database first' if they prefer to work directly with the database, manually crafting their database schema, or if they are using tools like SQL Server project to manage database schema changes.

  • What command is used in the Package Manager Console to create a new migration in EF Core?

    -The command used to create a new migration in EF Core is 'Add-Migration' followed by a name for the migration.

  • What does the 'Update-Database' command do in EF Core?

    -The 'Update-Database' command applies any pending migrations to the database, bringing it up to date with the current state of the application's model.

  • What is the significance of the 'Up' and 'Down' methods in a migration class in EF Core?

    -The 'Up' method in a migration class is used to apply the migration and update the database schema, while the 'Down' method is used to revert the changes made by the migration, effectively rolling back the schema to its previous state.

  • How can developers ensure that their local database is in sync with the latest model changes without affecting the production database?

    -Developers can use the 'Update-Database' command locally to apply migrations and keep their local database in sync with the latest model changes without affecting the production database.

  • What is the recommended approach for applying migrations in a production environment or when working with a team?

    -In a production environment or team setting, it is recommended to generate a SQL script using the 'script-migration' command, which can be reviewed and applied by DBAs as part of the deployment process.

  • Why is it not advisable to apply migrations directly to a production database that is accessed by multiple servers?

    -Applying migrations directly to a production database accessed by multiple servers can lead to conflicts and inconsistencies, as different servers may try to apply changes at the same time.

  • How can developers keep track of which migrations have been applied to a database?

    -EF Core maintains a special table (with a name that starts with double underscores) in the database to keep track of which migrations have been applied.

  • What does the 'Remove-Migration' command do in EF Core?

    -The 'Remove-Migration' command undoes the last migration that was added but not yet applied to the database, allowing developers to make changes to their model without affecting the migration history.

Outlines

00:00

🎥 Introduction to EF Core Migrations

James Montemagno hosts the 'On Dot Net' episode, featuring Brice Lambson, an expert on Entity Framework Core (EF Core) migrations. The episode aims to demystify EF Core migrations, a topic that is considered crucial for database schema management. Brice, a member of the EF Core team for nearly 12 years, discusses his role and the importance of migrations in evolving database schemas alongside application development, akin to version control for source code.

05:01

🛠 Understanding EF Core Migrations

The conversation delves into the practicality of EF Core migrations, contrasting two primary database development approaches: database-first, where the database is the source of truth, and code-first, where application code dictates the database schema. Brice explains the scenarios where migrations are essential, such as synchronizing schema changes among developers and preparing for application deployment with an updated database schema. The discussion also touches on the limitations of automatic schema changes in SQLite and the need for a migrations framework for more complex modifications.

10:03

🚀 Getting Started with EF Core Migrations

Brice guides viewers through the initial steps of setting up EF Core migrations. He demonstrates how to install the necessary tools using the NuGet package manager console and emphasizes the importance of creating an initial migration to define the starting point of the database schema. The process involves generating a migration class with up and down methods that represent the changes to be applied to or removed from the database, respectively.

15:05

🔍 Anatomy of an EF Core Migration

This section provides an in-depth look at the structure of an EF Core migration file. It explains the purpose of the up and down methods within the migration class and how they are used to apply or revert database schema changes. The discussion highlights the use of a timestamp in the migration filename to maintain a chronological order of migrations. Additionally, Brice explains the role of the migration's designer file and the model snapshot in tracking and applying migrations.

20:07

🔄 Modifying and Managing Migrations

Brice illustrates how to modify an existing migration by making a schema change in the application code and then creating a new migration to reflect that change. He also discusses the use of 'remove migration' to undo a migration that was not yet shared with the team, comparing it to amending a Git commit. The importance of keeping migrations in sync with the application model is emphasized, and the potential issues of editing migration files directly are highlighted.

25:08

📚 Applying Migrations and Best Practices

The episode continues with Brice applying the 'AddPostAuthor' migration to the database using the 'Update Database' command. He explains the implications of applying migrations to a shared database and the importance of considering the impact on team members and production environments. Brice also discusses the use of SQL scripts for deployment, particularly in server scenarios where multiple instances access the same database.

30:09

🌐 EF Core Migrations in Different Scenarios

Brice addresses the question of how EF Core migrations handle databases that do not exist on a server. He differentiates between client applications, where migrations can be applied at startup, and server scenarios, where a more controlled approach using SQL scripts and DBA review is recommended. The conversation wraps up with a brief mention of EF Core documentation and additional resources for further learning.

35:10

🎉 Conclusion and Resources

In the final segment, James expresses his appreciation for Brice's detailed walkthrough of EF Core migrations, which he plans to rewatch for better understanding. Brice provides a final recommendation to visit the official EF Core documentation for more in-depth information. The episode concludes with a reminder for viewers to engage with the content by asking questions, subscribing, and following the show for updates.

Mindmap

Keywords

💡Entity Framework Core (EF Core)

Entity Framework Core is an open-source, lightweight, and extensible version of the Entity Framework data access technology. It provides a simple yet powerful way to work with relational databases using .NET. In the video, EF Core is the central theme, as the discussion revolves around its capabilities for database migrations, which are essential for evolving the database schema as the application evolves.

💡Database Migrations

Database migrations refer to the process of managing changes to a database schema over time. In the context of the video, migrations are used to evolve the database schema as the application changes, similar to how version control is used for source code. The script discusses EF Core migrations, which are a way to apply these changes in a structured and version-controlled manner.

💡Brice Lambson

Brice Lambson is a member of the EF Core team and a guest in the video. He has extensive experience with EF Core and is brought onto the show to demystify the concept of EF Core migrations. His insights and explanations provide a deeper understanding of the topic for the viewers.

💡Reverse Engineering

In the realm of databases, reverse engineering is the process of creating a data model from an existing database schema. In the video, Brice Lambson mentions working on reverse engineering, which is a feature in EF Core that allows developers to generate a model from an existing database, which can then be used for further development or understanding of the database structure.

💡Code-First Workflow

The code-first workflow is an approach in EF Core where the application code is the source of truth, and the database schema is generated based on the code. This is in contrast to the database-first approach, where the database schema is defined first, and then the application code is generated from it. The video discusses the code-first approach as a scenario where migrations are particularly useful.

💡Model Snapshot

A model snapshot in EF Core is a representation of the current state of the model at a specific point in time. It is used by the migrations framework to understand what changes have been made since the last migration. In the video, the model snapshot is mentioned as a crucial part of the migration process, helping to track changes and generate new migrations accordingly.

💡Up and Down Methods

In the context of EF Core migrations, the 'up' and 'down' methods define the operations to apply and revert a migration, respectively. The 'up' method contains the code to apply the migration and update the database schema, while the 'down' method contains the code to revert the changes. These methods are central to the script's discussion on how migrations are structured and executed.

💡SQLite

SQLite is a C-language library that implements a small, fast, self-contained, high-reliability, full-featured SQL database engine. It is used in the video as an example of a database that can be managed using EF Core. The discussion includes how EF Core interacts with SQLite and the specific considerations when using it with migrations.

💡Data Annotations

Data annotations in EF Core are attributes that can be applied to model classes and properties to configure the model at design time. They provide a way to decorate model properties with metadata that EF Core can use to understand and enforce certain constraints, such as making a property required, as demonstrated in the video.

💡Onion Migration

An onion migration, though not explicitly mentioned in the script, is a concept related to migrations where each layer of the 'onion' represents a different aspect of the application that needs to be updated as part of the migration process. The video touches on the idea of applying migrations in a layered and structured manner, similar to the onion migration concept.

💡Version Control

Version control is a system that records changes to a file or set of files over time so that developers can track and manage those changes. In the video, version control is used as an analogy to explain how database migrations work. Just as version control tracks changes to source code, migrations track changes to the database schema.

Highlights

Brice Lambson from the EF Core team joins the On Dot Net podcast to demystify Entity Framework Core migrations.

EF Core is one of many options for database migrations, which are essential for evolving the database schema as the application evolves.

Database schema migrations are similar to version control for source code, allowing developers to record and share changes to the database schema.

Brice has been working on the EF Core team for almost 12 years, focusing on migrations, reverse engineering, and other core functionalities.

SQLite Dash Net automatically handles additive changes to the database schema, but migrations are necessary for more complex changes.

EF Core migrations allow developers to keep their code as the source of truth and generate database schema changes from the code.

The EF Core migration workflow is explained, including creating an initial migration and applying it to the database.

The anatomy of a migration includes an up method to apply changes and a down method to revert them, encapsulated within a migration class.

Migrations are version-controlled and can be committed, amended, or rolled back similar to Git commits.

The importance of naming migrations with descriptive names to act as commit messages for the database schema changes is discussed.

EF Core uses conventions to minimize configuration, allowing developers to write less code by following certain patterns.

The process of altering a column in SQLite requires EF Core to recreate the table due to SQLite's limitation on altering columns.

EF Core migrations can be used in team environments to keep everyone's local databases in sync with the evolving schema.

For server scenarios, EF Core recommends generating a SQL script for migrations that can be reviewed and integrated into the deployment process.

The podcast wraps up with a discussion on best practices for using EF Core migrations in different development environments.

Brice Lambson provides valuable insights and tips for new developers getting started with EF Core and database migrations.

The episode concludes with a reminder to check the official EF Core documentation for more detailed information and guidance.

Transcripts

play00:00

>> Tune in to this week's On Dot Net,

play00:02

where I have my good friend Brice on,

play00:03

who's going to demystify

play00:05

entity framework core migrations, so tune in.\

play00:11

[MUSIC]

play00:18

>> Hey, everyone, I'm James Montemagno and I'm back

play00:20

with another On.Net episode this

play00:22

time probably one of

play00:23

my favorite topics of all time because I know nothing about it,

play00:26

which is all about database migrations with entity framework core.

play00:29

I brought none other than

play00:30

my best friend in the entire world, Brice Lambson.

play00:32

How's it going Brice?

play00:34

>> Howdy, it's surreal being here.

play00:35

I remember when this show premiered in 2016,

play00:39

I've been a fan ever since. I'm honored to be on.

play00:41

>> I'm super excited because everyone on

play00:44

the EF core team is just like, you got to have Brice on,

play00:46

you got to have Brice on because I'm like,

play00:48

I don't know anything about anything.

play00:52

You're on the EF core team, correct?

play00:54

>> Yes.

play00:55

>> Yes. How long was it?

play00:56

How long have you been on the EF core

play00:57

team and what all do you do there?

play00:59

>> Oh, man. I've been on there almost 12 years now

play01:02

and I've been working on migrations almost since the beginning.

play01:06

I work on reverse engineering,

play01:08

I work on a lot of cycle light stuff.

play01:10

Those are the things I remember right now.

play01:13

>> What would you say, now, if people are just turning in,

play01:15

they're like, I'm in database migrations. I love that.

play01:18

What is the pitch for EF Core in general?

play01:21

Why are people using the EF Core and why is it so important?

play01:24

>> Yeah, EF Core is just one of many options.

play01:28

Database migrations have been around,

play01:30

specifically database schema migrations

play01:33

in other word migrations is very overloaded.

play01:35

We're talking here about your database schema,

play01:37

which is all the tables like columns,

play01:39

the foreign keys, all that database stuff.

play01:42

Migrate data schema migrations is

play01:45

a pattern for really

play01:48

evolving that schema as your application evolves,

play01:51

as the requirements change.

play01:53

You can think of it a lot like version control,

play01:57

which is for your source code.

play01:58

You record what changes you make to

play02:00

your source code so you can share those with other developers.

play02:04

Schema migrations are the steps to

play02:07

evolve your schema as your application evolves.

play02:10

They definitely weren't invented by EF,

play02:12

they existed long before.

play02:14

If you've ever used Ruby active record had migrations before us.

play02:19

Even way back in the day I remember manually

play02:22

writing little tiny bits of

play02:24

sequel and checking them in the repository.

play02:27

That's the pattern, it's recording the changes to the schema.

play02:32

>> I have a database, I have a person,

play02:35

for example, and I have a first name,

play02:36

last name and I deploy that application and then I'm like,

play02:39

oh, I forgot to add a middle name.

play02:41

Is that the scenario that I need

play02:43

a migration or is it a scenario where I'm like,

play02:47

oh, actually, I put it as a string,

play02:50

but it should really be an integer or something.

play02:51

Are those both examples that I just listed as migrations?

play02:54

>> Yeah, definitely. I think there's two big use cases.

play02:57

One is for everyday development,

play02:59

just like virtual control.

play03:00

Like I'm working on a feature,

play03:03

my teammate's working on a feature and we're

play03:06

both evolving the database schema and I don't want him to

play03:08

break me while I'm trying to work on

play03:10

my feature and so it's just everyone being on

play03:13

the same page in terms

play03:15

of their local database that they're testing with.

play03:18

Then you also mentioned deployment and

play03:20

that's another things like, oh,

play03:22

we need to ship Version 2,

play03:24

all the databases are still in Version 1.

play03:26

How are we going to not delete

play03:28

all their data and yet update their databases?

play03:31

Those are the two big scenarios.

play03:33

>> Got it. Now, how come it just

play03:34

doesn't magically happen for free?

play03:36

Because I come from the mobile world where I

play03:38

use SQLite Dash Net and I'm

play03:40

just slang in Pogo objects everywhere,

play03:45

adding stuff, removing stuff.

play03:47

It just does it automatically, I think.

play03:50

How come that just can happen?

play03:51

>> Yeah. Frank Kruger is a ninja.

play03:54

SQLite Dash Net,

play03:56

it hides all those stuff from you.

play03:57

It's really good at additive changes.

play03:59

In fact, it's so good you don't even know it's doing it.

play04:02

You just hand it data and it says,

play04:04

oh, I need to put this data somewhere.

play04:06

I'm going to create a column for you.

play04:07

I'm going to create a table for you.

play04:09

Additive changes, you've probably never even

play04:11

encountered those database schema. It works.

play04:15

It gets a little tricky when you want to

play04:17

split the name column into a first name and a last name.

play04:21

That SQLite Dash Net will then

play04:24

create two new columns and the old one is just there.

play04:28

Yeah, you need to grow up into a migrations framework.

play04:33

If you're using SQLite Dash Net,

play04:35

there's a really great library called Fluent Migrator,

play04:39

I think is what they call it and same with

play04:41

Dapper, you're not using EF.

play04:43

You probably don't want to use EF just for migrations.

play04:46

There's another library that encapsulates this pattern

play04:50

of recording the steps to

play04:51

your database and you write it all in C-sharp codes.

play04:54

You don't really need to know SQL.

play04:56

That's the real beauty of a migrations framework.

play04:59

>> Got it. That's super cool. I've been

play05:01

getting into the web world where

play05:03

EF Core seems like just the de

play05:05

facto as a donor developer that I'm going to use,

play05:08

it's built into templates and beautiful scaffolding.

play05:10

I think the very first time I was going

play05:12

through an MS Learn module in the Kamro,

play05:15

it was I'll create this thing and run a migration.

play05:17

I was like I have no idea what's happening right now.

play05:20

I clicked a button and things happened.

play05:22

I was hoping that you could demystify that in a logical step.

play05:26

I'm brand new, which I am,

play05:29

by the way, to this.

play05:30

What am I actually doing or what is

play05:32

happening and how does the tooling going to help me?

play05:36

>> Yeah, before we get there.

play05:38

As with any tool, you need to stop and ask yourself,

play05:40

is migrations even the right tool for me?

play05:43

There's a lot of people who really love writing SQL,

play05:47

they like to craft their database by hand.

play05:49

They might have a SQL server project and they add tables to it.

play05:53

It's the source of truth,

play05:56

if you will, for the model.

play05:58

Everything flows from the database.

play05:59

You want to add something to the database,

play06:01

you go change the database and then

play06:03

it flows back into your application.

play06:07

The SQL server project tools

play06:10

have a really cool thing called schema.

play06:11

Therefore, you model your table and then you say, okay,

play06:14

I want to make these changes to this database

play06:16

and it will go out and make those changes.

play06:19

We like to call this a database

play06:22

first workflow on entity framework.

play06:24

If you love doing this,

play06:26

if this is how you work,

play06:27

migrations are for you.

play06:28

>> Okay.

play06:29

>> Continue writing your little SQL scripts or

play06:33

using the database project deploy tools.

play06:36

In fact, there's a really cool project called DB app,

play06:40

which is associated with Octopus deployment,

play06:42

you can use it outside of that.

play06:43

All it is is a little console app that you add

play06:46

your SQL scripts to and

play06:48

then it can just apply those to a database.

play06:50

It takes care of the tedious part of running

play06:53

those one by one and making sure they run in order.

play06:57

Yeah, that's the tool if that's your workflow.

play07:00

>> Okay.

play07:01

>> Where migrations really

play07:02

shine is on the other end of the spectrum,

play07:04

you want your code to be the source of truth.

play07:08

You want to add a feature, the first

play07:09

place you think to go is go change

play07:11

my app code and change it there and so we call this code first,

play07:17

although you don't have to start with the code first,

play07:21

but we like to call this code first because it's

play07:24

the code is the source of

play07:25

truth and then everything flows from there,

play07:28

whether that's you change your domain model in

play07:32

your application and then you go write a migration

play07:35

or you have it generated for you in the case of EF.

play07:40

That's the flow there.

play07:41

>> Got it. That makes a lot of sense where it's like

play07:44

I see where you're coming from is like, hey,

play07:47

this database is controlling the scheme

play07:50

and that is the source of truth or the code,

play07:54

like you said, code for database first code first make sense.

play07:56

The code and that's what I'm used to is like,

play07:58

here's my person in class, here's the thing.

play08:00

I'm like, database, please be

play08:03

what I want you to be basically instead of

play08:05

the vice versa which is database you are

play08:08

this and my code will react to that. Did I summarize that correct?

play08:12

>> Yeah, and if your database is the source of truth,

play08:15

we have something called reverse engineering or scaffolding.

play08:18

You would make those changes to the database and then you just re

play08:21

scaffold your model and it would

play08:22

bring in all those changes for you.

play08:23

That's a tool for that. But if we

play08:26

want to look at what it looks like.

play08:28

>> Yeah, it's all right. You want to bring

play08:31

up your monitor and we'll give it a look. Cool, I see it.

play08:36

>> Here's my super simple application.

play08:38

It's just a console app. I'm not fancy.

play08:41

EF works anywhere, you can imagine it works in.NET MAUI projects.

play08:47

You are an Android app and we work on Blazor WebAssembly.

play08:52

If you want to write a little SQL database

play08:54

on the client side of the browser,

play08:56

which is like mind blowing, you can do that.

play08:59

As you mentioned, it's very popular with

play09:01

server side applications if you have a web API.

play09:04

A lot of times you go through.

play09:05

Just a console out today just to keep things simple for this demo.

play09:09

>> Okay.

play09:10

>> Here I have a blog context and this is

play09:12

the EF's entry point into the database and then on it.

play09:18

Right here is just an if statement,

play09:19

if I don't have any posts,

play09:22

add some sample ones just for

play09:24

the sake of having it in our database,

play09:26

and then go through every post

play09:28

in the database and just write them out.

play09:30

>> Looks super duper simple.

play09:32

That blog context,

play09:33

that is, something that's important.

play09:36

>> Yeah. Let's have a look at that.

play09:38

>> Okay.

play09:38

>> I have it over here in my model.

play09:40

It is just a class that inherits from

play09:42

the DB context and this is just entity framework magic.

play09:44

You don't really need to know what it even does.

play09:47

Then you have these things called DB sets and these map,

play09:51

one to one to a table.

play09:52

>> Okay.

play09:53

>> Gross table.

play09:55

>> DB set is like a table and then that table is

play09:58

going to have columns with different items in it,

play10:00

basically, like what is a post? Is that correct?

play10:03

>> Yeah, and if you've ever heard the term like a unit of work,

play10:06

I'm creating a new blog context is like saying,

play10:09

I'm starting a unit of work.

play10:10

I'm going to make some changes to the database

play10:12

or I'm going to get some stuff out of the database.

play10:14

You create a new one of these to go back to program,

play10:17

you create a new one of these,

play10:18

make the changes, and then commit

play10:21

that unit of works persist everything to the database.

play10:24

>> Is that what we would call a

play10:26

transaction basically at that point?

play10:28

>> Yeah, every time you call save changes there,

play10:31

it wraps all these changes right here.

play10:33

It's adding three rows to the database in a single transaction.

play10:37

If it fails, you end up somewhere in the middle.

play10:40

>> See, I know a little bit of the lingo,

play10:42

but yes, Frank has hidden most of it from me.

play10:46

I get it. Perfect.

play10:49

>> Then just in here, I'm using SQL lite.

play10:53

EF call works with all databases, PostgreSQL,

play10:57

we work with MySQL,

play11:00

SQL Server obviously,

play11:01

Azure SQL, you name it.

play11:03

There's lots of providers. I like SQL 8 because it's simple.

play11:08

Here I'm just writing to a file called Blogs.db.

play11:12

Then here I have my plain old sale,

play11:15

or object, my pocker for my model.

play11:18

This could flow all the way into your views if

play11:20

you are writing like a client side up.

play11:22

Here's a post it has an ID.

play11:25

Lots of database is just use

play11:27

surrogate primary keys they call them just to keep track.

play11:32

Because there's no such thing as like an instance.

play11:34

You can't just take

play11:35

an instance out of the database and shove it in a C-sharp,

play11:38

this identifies this piece of

play11:40

data and it has a title and it has some content. Super simple.

play11:46

>> Nice.

play11:47

>> I've got my app written,

play11:49

my super cool app.

play11:51

I'm ready to run it. Let's see what that looks like.

play11:54

>> At this point, you haven't really done

play11:56

any these usual code basically.

play11:58

>> Yeah. This is all just plain old.

play12:01

Immediately I had an error.

play12:03

>> Oh my goodness. It's ah.

play12:05

But what's going on because I thought you are all about,

play12:10

EF on the EF team,

play12:11

how could this happen.

play12:13

>> It says there's no such table posts.

play12:16

I don't have a database.

play12:18

I never created the database.

play12:20

I wrote on my code and I went to query

play12:22

it and it threw it because it couldn't find any data.

play12:24

I couldn't even find the database.

play12:26

Let's look at what it looks like to actually create the database.

play12:30

The first step is to create a new migration.

play12:35

For this we use the NuGet package manager console.

play12:43

Is a little tool here, and this is an odd little thing.

play12:47

You can think of it as like a console

play12:49

that knows more about Visual Studio.

play12:52

You can actually use those to install packages.

play12:54

The first step, when you want to get started,

play12:56

you need to install the tools.

play12:59

>> You're bump that up for me on that little 100 down there.

play13:03

>> It works.

play13:04

>> Yeah keep it going a little bit more.

play13:07

>> Here we go.

play13:08

>> Perfect.

play13:08

>> It's really big. I'm going

play13:13

to use this to install the tools as an airbag.

play13:15

You could also right-click on

play13:17

your Solution of managing the packages.

play13:19

I just put it in the console here to get used to it,

play13:22

because you're going to see it here in a minute

play13:23

when we start using migrations.

play13:26

>> I need this, so even though it's

play13:28

just like initializing the database,

play13:31

I'm still creating a migration that gets an initial migration.

play13:36

>> Yeah, your very first migration

play13:39

is going to go from nothing to something.

play13:41

You're going to create the schema as it

play13:43

is right now in your account.

play13:45

>> Got it, I think that was always my confusion because I'm like,

play13:47

I'm not really migrating anything, but that makes sense.

play13:49

You are migrating from you had nothing to this is the thing

play13:53

that you want in v1. V0 to v1.

play13:57

>> I'm going to install this tools package.

play14:00

All it does is just add a package to my CS project.

play14:04

Well, that's really big.

play14:06

I think those are linked together.

play14:07

I'm not going to zoom out yet, so I'm going to keep working here.

play14:10

>> Okay.

play14:12

>> Now I have these tools installed and they

play14:15

add a few commands you don't have to use.

play14:18

This is the Visual Studio way of doing it.

play14:21

There's another way if you're working

play14:24

in like Visual Studio or outside of Visual Studio,

play14:26

like Visual Studio from Mac or of your code or if you like,

play14:30

Emacs or VM or whatever.

play14:32

You can do all this stuff on the console and

play14:35

the way you do that is just go in that tool install.

play14:38

I like to install it globally,

play14:39

so that's available everywhere.

play14:41

It's just a tool called.Net EF.

play14:44

>> Cool.

play14:45

>> This is the command line way.

play14:48

If you're a console junkie and you like black and colorful text.

play14:53

Then it has similar commands

play14:56

to what you're going to see in a minute.

play14:58

You just invoke it with.NET EF.

play15:01

You get to see this cool little unicorn.

play15:05

>> You can't be [inaudible] I mean, come on.

play15:07

>> For sure. I actually created that.

play15:10

I put it in as a joke with the team.

play15:12

Let me keep it, so I was excited.

play15:14

It has migrations, commands.

play15:17

It has commands for working with the database or the data context.

play15:20

This is a command-line way of doing it.

play15:22

I'm not going to show that because I like using Visual Studio.

play15:25

I like to stay in Visual Studio.

play15:28

There's PowerShell command for the same thing.

play15:33

Right now we're going to add a migration.

play15:36

We're going to just call it InitialCreate.

play15:40

Now, this is like a get republic or I have like

play15:42

my first command where I add all my code.

play15:45

I'm going to add all my schema as it

play15:47

is now so I can start evolving it.

play15:49

>> Is that initial create,

play15:52

is that just a tag that you set or

play15:53

is that actually a keyword that's of importance?

play15:55

>> This is the name of the migration.

play15:58

You can think of it as like a commit message,

play16:00

and the way it comes out is it

play16:02

actually becomes the class name here.

play16:05

>> Interesting. I'm not

play16:08

going to spoil it, you're going to do much cool stuff.

play16:10

I'm not going to stop [inaudible].

play16:12

>> Yeah, you see over here,

play16:13

by default, it creates a migrations folder.

play16:16

Then you can see the initial create there,

play16:19

and it puts this big old time stamp in there.

play16:22

The reason it uses the time stamp

play16:24

is to help keep everything ordered correctly,

play16:27

because at the end of the day, they're

play16:28

just files on the file system.

play16:30

But if you can see like the sequence of

play16:33

changes and if your team's

play16:34

working on something else and you merge in their changes,

play16:37

you see when they made their change.

play16:39

>> Got it. That makes sense.

play16:41

>> Let's look at the anatomy of a migration.

play16:44

You get this class that has an up method and it has a down method.

play16:49

The up methods bring the database up to date

play16:53

with this migration where your model was at, in this migration.

play16:58

It has this funny little DSL,

play17:01

looks like SQL,

play17:02

but it's very C Sharp as well.

play17:04

We're going to create a table,

play17:06

so the post table has an Id,

play17:09

has a Title, has Content,

play17:11

it's got a PrimaryKey, that Id column.

play17:15

One thing here, though

play17:18

the title here says that it's knowable true.

play17:21

That was like a mistake, like, oops,

play17:23

I'm not ready to share this with the team.

play17:27

I'll show you in a minute. We're going to get to that.

play17:30

Let me finish going through the anatomy.

play17:31

>> Okay, got you.

play17:32

>> I getting ahead of myself, so excited.

play17:35

All right, the down method

play17:37

obviously if you unapply this database,

play17:39

you go back to nothing and so we drop the only table we created.

play17:42

>> A drop is like a deletion?

play17:45

>> Yeah. It'll delete the table

play17:47

and all of its data from the schema in the database.

play17:51

>> These are just helper methods,

play17:52

no one's calling this yet.

play17:54

These are methods that you could call.

play17:56

I guess you could new up

play17:57

an initial create and then call those methods.

play18:02

>> Interesting point. When this method right here is called,

play18:06

it doesn't actually create a table.

play18:08

This tells EF to generate SQL in order to create a table.

play18:13

That is a very important distinction.

play18:15

This is defining the script.

play18:17

This isn't actually just finding

play18:19

like execute this code procedurally.

play18:22

It's a little language that EF uses to represent a migration.

play18:27

It's abstracted away from the specific database.

play18:30

Like you can see traces of,

play18:31

oh you're using SQLite,

play18:32

we're going to throw in an Autoincrement there.

play18:34

But in general like whether you're using MySQL,

play18:37

PostgreSQL server, all the migrations use the same language here.

play18:42

>> Got it. Cool that makes sense.

play18:44

It knew that the idea

play18:47

to autoincrement that was the thing, just EF magic?

play18:50

>> Pure EF magic, yeah.

play18:53

You can type every little thing about your model saying this is

play18:58

the primary key and I want to use this database type.

play19:02

EF has just a ton of conventions.

play19:05

By default, it will look for

play19:07

an integer or I don't even think I was doing integer.

play19:09

It just has to be a column named Id,

play19:11

and that will be your primary key.

play19:13

So if I wanted to call that key,

play19:14

suddenly EF wouldn't know what

play19:16

the primary key was and you'd have to go and tell it.

play19:19

>> Got it.

play19:20

>> We call it convention over configuration.

play19:23

You don't want to go configure everything,

play19:25

so we have these conventions and if you

play19:27

follow them you can write less code.

play19:29

If you don't follow them, you can tell us

play19:31

what we don't know, tell EF how to do it.

play19:34

>> Cool.

play19:35

>> Back to the anatomy of a migration.

play19:39

Underneath this little initial create with the up and down,

play19:42

there's this designer file.

play19:45

Peel back the curtain and look behind and see what's here.

play19:48

You don't really need to know about this.

play19:50

All of this is a snapshot of

play19:53

your model and it's almost never used.

play19:57

It's just here in case when we're generating that

play20:00

SQL we need additional information and a look here.

play20:04

One cool example is on SQLite.

play20:07

You can't actually alter a column, they don't support that.

play20:11

One of the things we have to do is we

play20:13

have to rebuild the entire table,

play20:15

like recreate it in a new place,

play20:18

copy all the data over and delete it.

play20:20

All just for a little alter column.

play20:22

The alter column clearly isn't enough to do all of that,

play20:25

so we'll actually peek back here and say, okay,

play20:28

when we recreate this table,

play20:29

it's going to need all this additional information.

play20:31

This is like a last resort though.

play20:32

>> Got you.

play20:33

>> Because we can, we use the stuff that's right here.

play20:36

>> Okay, cool. It's cool that it's there.

play20:39

>> Yeah. Good to know it's there. Don't delete it.

play20:42

It might be used. The other thing

play20:45

we get as a model snapshot and it's exactly the same thing.

play20:48

It is another snapshot of your model at this point in time.

play20:52

This one has a very different purpose.

play20:55

This is so that the next time you call on migration,

play20:58

we know where we're coming from.

play21:01

Because if you're just changing your apps model

play21:03

like we don't know.

play21:05

All we have is an up and down method.

play21:07

This tells us create an up and down method for

play21:11

the changes between the snapshot

play21:14

and then when you generate a new migration,

play21:17

this snapshot will be overwritten with

play21:18

the next current model on the next current model.

play21:20

>> Got it. What you're

play21:23

saying is like this is the current snapshot in time

play21:25

and then the migrations

play21:28

would build up all the changes that you made do it.

play21:31

>> Yeah.

play21:31

>> Okay.

play21:33

>> All right, so that's the anatomy of a migration.

play21:37

Like I said, I don't like

play21:39

that you can add

play21:42

a post without a title. That doesn't feel right to me.

play21:45

I want to go back and I want to make that required.

play21:48

The good news is I haven't shared this migration with anyone,

play21:51

so I can just go and actually delete all this stuff.

play21:55

But again like if you've added two migrations you don't want to

play21:58

just delete the snapshot because that it will be completely lost.

play22:01

>> Got it.

play22:02

>> There's another command to sort of keep all this stuff in

play22:05

sync and it's removed migration.

play22:09

>> This is kind of you're playing

play22:11

around with it. You're a developer.

play22:14

You think that you did it but actually you didn't do it.

play22:18

You're like I messed up, rollback.

play22:21

I don't want to go into Git and

play22:23

undo everything because you don't want to

play22:25

mess up all your code changes basically.

play22:26

>> Yeah. I really

play22:28

like thinking about version control in this context.

play22:31

Like, oh I thought I was ready to

play22:33

commit my changes and push and send a PR.

play22:35

Whoops, I'm not quite ready,

play22:36

so let me go back and sort of

play22:38

amend that last commit and Git lingo.

play22:40

>> Got it.

play22:41

>> I'm going to undo this migration.

play22:43

I want to take this one away.

play22:45

I'm not ready to share this with anyone.

play22:46

It's not in the way I want it to be.

play22:48

Remove migration just sort of removes the last migration.

play22:52

>> Okay, just like the last one in general?

play22:54

>> Yeah. While keeping

play22:56

the snapshot in sync and everything like that.

play22:59

Of course it was my first one, so I just deleted it.

play23:01

All right, let's go and make that column actually required.

play23:07

I'm just going to use data annotations

play23:10

here because they're simple to understand.

play23:12

>> This is part of EF Core or?

play23:17

>> Yeah, this is part of EF Core.

play23:19

There's two ways to do things.

play23:21

One is with these annotations,

play23:23

the other is to override on model creating.

play23:27

It's a lot more code but some people really prefer that.

play23:31

Then you could say modelBuilder.entity Post.

play23:38

This property, oops I forgot my parenthesis.

play23:42

The Property Post.

play23:46

You can see it's a lot more code.

play23:49

>> Yeah.

play23:50

>> The dot is required.

play23:53

>> Oh, wow. Okay.

play23:54

>> If you really want to write it this way you can.

play23:57

One of the reasons people don't like

play24:00

these annotations is that they pollute your POCOs.

play24:03

It's not really a POCO anymore.

play24:05

It knows more about how it's resisted.

play24:08

I think required doesn't really fit that definition

play24:12

because your UI layer might use this for validation.

play24:16

>> Yeah, sure.

play24:17

>> It's just a flavor.

play24:19

There is no right or wrong way.

play24:21

We just allow different ways of doing things.

play24:23

>> Yeah. I've definitely seen people that I really,

play24:26

really want my model to be in

play24:28

a completely separate library

play24:33

and it should do nothing about anything.

play24:35

That's cool that there are those two options.

play24:37

>> Yeah. Let's look at that one again.

play24:42

All right, and now we can see that

play24:45

the title column is not nullable.

play24:48

You must specify one of these.

play24:50

>> Got you. You needed to do it there.

play24:52

You couldn't just go on and change.

play24:54

You should really never change these files basically.

play24:56

You shouldn't touch them.

play24:57

>> I wouldn't say that. You may want to change

play25:01

these but don't change them in a way

play25:04

that is out of sync with your entity framework model.

play25:08

You could say now it's required in my domain model but actually,

play25:13

I want to allow some bad data in there.

play25:17

You want to relax some constraints.

play25:20

My application should never insert this data but if

play25:24

some bulk update happens to

play25:26

import data without null then maybe it does. I don't know.

play25:29

But yeah, in general you probably don't want to edit these.

play25:33

You may want to tweak them a little bit.

play25:35

But not in the way that disagrees

play25:37

with what you already wrote in your classes.

play25:39

That's kind of the definition of insanity. Your model is not sane.

play25:43

>> Got you. Cool.

play25:45

>> Now I have this migration.

play25:49

It's the way I want it to be.

play25:51

I'm going to go ahead and actually create my database now.

play25:55

I'm going to apply this migration to the database.

play25:58

There's a simple command called Update Database.

play26:02

If I do dash verbose,

play26:04

we're going to see a bit more output here just so you can go wow.

play26:08

You can see a bit more of what's going on here.

play26:12

>> This is like creating it on your local machine?

play26:15

>> Yeah, it's creating it actually right here in my directory.

play26:19

In fact, let's look at the database here.

play26:21

Here I'm using the SQLite toolbox

play26:24

by Erik Jensen, a good friend of the EF team.

play26:27

It's just a simple way of inspecting SQLite databases.

play26:32

Here's the post table created an ID with a primary key.

play26:36

It's got a title column, not nullable.

play26:38

It's got a content. In here there's this other little table.

play26:42

It has double underscore, so you know

play26:44

it's special, don't touch it.

play26:46

>> Yeah, that's super special.

play26:47

Not just one underscore but two underscores.

play26:49

>> Two underscores, yeah.

play26:51

This is how EF keep track of which

play26:53

migrations have been applied to the database.

play26:55

Again, like you're working in a team environment, you pull.

play26:58

You need to apply your teammates migrations to your database,

play27:03

needs to keep track of which ones.

play27:04

If we actually look at this data,

play27:05

you can just see there's that initial create, it's been applied.

play27:09

>> Oh, cool.

play27:09

>> You can even keep track of what version you

play27:11

used to apply it. Just for fun.

play27:13

>> Nice.

play27:15

>> Now when we run our app everything should work

play27:19

because we have a database, has a schema.

play27:22

We can actually put

play27:23

data in the database. Let's go ahead and run it.

play27:26

>> Got it. There's nothing that you need to do.

play27:29

You don't need to call

play27:31

the migration in code because you've executed it here,

play27:37

so your database is up to date with the schema.

play27:40

It's executed the SQL commands to generate the tables.

play27:44

>> Oh yeah. Let's go back to that verbose output.

play27:47

See right here, you can see the create table post.

play27:51

That update database command,

play27:54

what it does, is it looks for the database.

play27:55

If it's not there, it will create the database if it can.

play27:58

It will see which migrations have been applied.

play28:02

It will generate the scripts for those migrations,

play28:05

the scripts being this create table right here

play28:07

and then run those against the database.

play28:09

>> Got it.

play28:11

>> This is very much like a developer time thing

play28:14

here, like a gesture.

play28:16

We'll look at other ways of getting migrations applied.

play28:20

Let's run our app and see if it actually works now.

play28:30

Did that work? Did it already run?

play28:33

>> It already run.

play28:34

>> Let's delete that database.

play28:36

Let's try all that again. It shouldn't

play28:37

actually have data in there.

play28:38

I'm surprised. Maybe I kept one around

play28:41

on accident. Update database. Now we run. There you go.

play28:58

Adding sample data,

play28:59

and now I was supposed to run

play29:01

it and it doesn't add the sample data,

play29:04

there we go the second time I "run" it,

play29:07

I doesn't have the data enlisted there.

play29:12

Let's look at making another change to the database here.

play29:16

For this one, let's add an author,

play29:21

so each blog post should have an author here.

play29:30

Now I've just changed

play29:32

my application code and

play29:35

that's enough for any framework to know what to do.

play29:38

Let's add another migration.

play29:39

>> Okay.

play29:40

>> We'll just call it AddPostAuthor.

play29:45

Something descriptive to help me know what's going on here.

play29:49

>> I saw that it autosave the file for you.

play29:53

>> Yes, that's really the beauty of using

play29:56

the package manager console commands

play29:59

as opposed to the command line interface,

play30:01

but it doesn't know anything about Visual Studio.

play30:03

>> Got it.

play30:03

>> You'll also notice it will pop up the file.

play30:06

Is that little, little things like that,

play30:08

that make it more integrated,

play30:11

which is why I still prefer it.

play30:14

Here we go. We're just going to add a Column,

play30:17

an Author Column to

play30:19

the Posts table and it's text, and on a level.

play30:23

>> Yeah, and I see you've just added it right below it,

play30:25

so the very first one and then it just goes down below.

play30:30

Because date, times stands basically.

play30:32

>> Yeah, definitely.

play30:35

Again, I haven't applied this to my database,

play30:38

so let's do that. Let's update database.

play30:41

It will look in the database, and say okay,

play30:44

I only need to apply this AddPostAuthor,

play30:47

migration has already been applied.

play30:50

Then if I refresh the database over here,

play30:53

it should have that author column.

play30:55

I expand everything again. There it is.

play30:58

>> How cool.

play30:59

>> Though that's not a super simple overview of

play31:02

the workflow of using migrations.

play31:05

Another interesting thing,

play31:07

now that I've applied this,

play31:09

if I actually try to remove it,

play31:13

it will warn you and say,

play31:16

you've already applied this to the database.

play31:18

You need to think about this a little more.

play31:20

because if have you share this with your teammates,

play31:23

it's like rewriting Git history.

play31:25

If you do a forced push,

play31:27

everyone's machine is going to be out of

play31:29

sync and it's going to be very hard to get it back.

play31:32

Before you just reverb and change your migration,

play31:35

you need to stop and think about,

play31:37

how does this migration then apply to other databases.

play31:39

If it has, don't remove it,

play31:41

just add another migration on top

play31:43

of it so that everyone can keep rolling forward.

play31:46

>> Got it, so in that case,

play31:47

would you then remove the author from

play31:49

your code and then run another migration?

play31:53

Then actually it would disappear.

play31:55

It would be like create it,

play31:58

add it, remove it.

play31:59

But then everyone's in sync, so it's okay?

play32:01

>> Yeah, definitely.

play32:02

>> Interesting, okay.

play32:04

>> Again, I have that version control mentality.

play32:06

This is very key to me here.

play32:08

I think it really helps you use Migrations correctly.

play32:11

>> Now I have a question for

play32:12

you and maybe I'm jumping the gun here,

play32:14

but you have a database that's here in your source code, right,

play32:19

that you would check in magically and to get or not in to get,

play32:22

maybe you would ignore that, so everyone's running it.

play32:25

What if that database doesn't exists on a server.

play32:30

How does it know when you start up your app that you need to run

play32:35

Migrations or do I need a VPN into

play32:37

a machine and run these commands in prod?

play32:41

>> Yeah, and the answer is it depends.

play32:45

Think about node development.

play32:48

There are thousands of databases on everyone's phone.

play32:51

You can't just VPN and run. You can't just change that.

play32:55

I hope you can't anyway that would be a total loss.

play32:58

You can't just change their databases.

play33:00

It needs to be part of an upgrade experience.

play33:02

Like, they've downloaded Version two of my app,

play33:05

their database is still at Version one.

play33:06

You need to roll it forward,

play33:08

and so in that case, where there's,

play33:10

a phone accessing a local database,

play33:13

it's absolutely safe to write here

play33:15

during app start to apply the Migrations,

play33:19

db.database.Migrate [inaudible] how you using here.

play33:24

There we go.

play33:27

This does basically the same thing as our update database,

play33:30

and only when your app is running it will find the local database.

play33:35

It will see which migrations need to be applied.

play33:37

If the database isn't there,

play33:38

it will create the database.

play33:40

This is super handy for client development.

play33:45

But if you think about this on a server

play33:48

where you're scale out to 10 nodes,

play33:50

all accessing the same database,

play33:53

they're going to be stepping over each other's feet.

play33:55

It's going to be a nightmare,

play33:57

and so we really don't recommend this on

play34:00

a server scenario unless you have

play34:01

a single server accessing a single database.

play34:04

>> Got it. That makes sense.

play34:08

>> [inaudible].

play34:09

>> Yeah.

play34:11

>> When you are in that server scenario,

play34:13

the one where we do recommend it,

play34:14

is the traditional way you generate

play34:17

a sequel script and there's a command for that too.

play34:19

It's just called script-migration.

play34:22

>> Okay.

play34:25

>> This is like an artifact that you can then go and

play34:28

hand Your DBAs who know everything about databases,

play34:32

they can review it,

play34:34

they can say, "Well actually you need

play34:37

an index here, when you create this table."

play34:39

They can review it. This can become

play34:41

part of your deployment process.

play34:43

>> Got it. That's really good, it's really nifty.

play34:45

There's all of these different commands built in,

play34:48

including, here's the sequel script. That's really cool.

play34:50

>> Yep.

play34:51

>> Nice. Anything else you want to demo through or it's covered?

play34:56

>> No, I could go on forever about this stuff,

play34:58

but I don't want to overload viewers.

play35:00

This is merely an introduction to how do I start using migrations?

play35:04

>> I think this is great because I honestly,

play35:06

I feel like sometimes I can walk through the tutorial,

play35:10

but I'm not actually getting the sense of

play35:11

exactly why or where all these files are out.

play35:14

To me, this is actually perfect.

play35:16

On that note episode I'm going to

play35:18

rewatch probably like 100 times is that every time I

play35:20

create a new EF Code database

play35:22

and I'm using anything, I'm going to go through all that.

play35:24

Brice this is absolutely perfect in every regard. I love it.

play35:27

>> I'm glad, and if you want to know more,

play35:30

are the docs, the docs.Microsoft/ef.

play35:34

There's all kinds of great docs in there about,

play35:36

Well I want to use SQL Server and SQL items in my application

play35:40

or what are some other tips you have for team environments?

play35:45

We have these things called bundles. What's a bundle?

play35:48

They were new in the episode.

play35:50

All kinds of more information,

play35:52

if you go and look at the docs.

play35:53

>> That's awesome and we will put links

play35:55

down in the show notes below

play35:57

regardless of where you're at or if you're on Docs

play35:59

right now or you're on YouTube, go down there.

play36:01

I'm going to get all those cool fancy

play36:02

extensions that Brice had as well,

play36:04

so everyone can install those.

play36:05

You're using Visual Studio and of course,

play36:07

also the Command-line stuff too.

play36:08

Brice, thank you so much for coming on and walking through this.

play36:10

This is absolutely delightful.

play36:11

>> Yeah, my pleasure.

play36:13

>> Awesome. Thanks, everyone, for tuning in.

play36:15

If you have any questions at all about anything but specifically,

play36:18

probably EF Core and Database Migrations,

play36:20

leave them in the comments below.

play36:22

If you're over on YouTube, I have Brice,

play36:23

go and check those out and comment back

play36:25

as well and I'll check on them too.

play36:27

If you're over on YouTube, don't forget to like

play36:29

this video and ring that notification bell.

play36:31

Hit subscribe so you get notified

play36:33

whenever we put out new YouTube videos here.

play36:35

Brice, thanks again for coming on.

play36:36

Thanks everyone for tuning in and have a great day.

play36:39

[MUSIC]

Rate This

5.0 / 5 (0 votes)

Ähnliche Tags
EF CoreDatabase MigrationsEntity FrameworkSchema ManagementCode FirstDatabase FirstData ModelingSoftware DevelopmentDevOpsTechnical Tutorial
Benötigen Sie eine Zusammenfassung auf Englisch?