>> On today's Visual Studio Toolbox, Phil Japikse is here
to kick off the series on how to use Entity Framework Core. [MUSIC] Hi, welcome to Visual Studio Toolbox. I'm your host, Robert Green, and joining me today is Phil Japikse. Hey, Phil. >> Hey, Robert, how are you? >> Great. Welcome back to the show. >> Thanks. Good to be back. >> It's been a while.
Phil Japikse is my guest, that means we're doing
a multi-part series. >> Absolutely. >> We've done some epic ones. We did an eight part on
design patterns awhile back. >> Yeah, still get lots of
great feedback on that series. >> Yes, I loved that one. Also did one on unit testing, was that like four
episodes or something? >> Five hundred nodal runs together
when you haven't so much that. >> I know. Today we're
going to kick off and we're going to take
a different approach to our series this time. We're going to do
Entity Framework Core. But we're going to start
from the beginning. This is going to be a introduction
to Entity Framework Core. >> Correct. So just if
you're watching this and you've been using
Entity Framework Classic, or if you've been tinkering
with Entity Framework Core, you might want to just double
the speed on this one. Later in this series, we'll do a deep dive into all the awesome source that
is in Entity Framework Core. But we want to get people up
to speed on ORMs in general, and of course, specifically,
in these first few episodes. >> So this is part 1 of a multi-part. Is it safe to say that
Entity Framework Core is to Entity Framework as ASP.NET
Core is to ASP. NET? >> Sure. >> So that is aimed at
the.NET Core runtime? >> Yeah, so if you want
to make that analogy, it is important to note
that both ASP.NET Core and EF Core are complete rewrites
of their classic versions. So they are similar in name, they are similar in goal, but under the covers they
are vastly different. >> But the way you use them is more the same than
different. Is that correct? >> That's correct. There's a lot of new features that came in EF Core that we'll cover
in later episodes. But from the general perspective
of an object-relational mapper, which is what EF is, the general concepts are the same. >> So I guess, that's
a great place to start because anytime
I see a technology, I like to ask, what is this thing? Why was it invented? What problems is it trying to solve, and then how do you use it? >> Correct. >> So what is an
object-relational mapper? What is Entity Framework? >> So databases tend to store
their data very relationally, hence the name relational databases. So you have a customers table, you have a products table, you have very specialized, it's called normalized
tables based on the data. The problem is our applications
don't work that way. We tend to work with domain objects. So if you're looking at a customer, you're also going to see that customer's orders and
their order details and their products related. So we have this disparity between what are our application needs and what is optimized for the database. So that's where the ORM or the object to relational
mapper comes in. So it enables us to very, very simply convert what is good for the database into what
is good for the application. >> Okay. So it's not about
how you talk to the database because we've been able to talk to the database for a very long time. In fact, before Entity Framework
was came on the scene, we were using ADO.NET, and before that we were using ADO, and before that other things. So it's less about the
underlying talking to the database and more about how you get to work with
the data in your apps? >> Yeah, correct. An Entity
Framework in any of our Core, both use ADO.NET or ADO.NET Core, and now, I guess, you would
call it, under the covers. So they're still
using data providers, they're still using connections, command objects and things like that. It just extracted away from you. So I look at it this way, everybody really appreciate
indoor plumbing. We don't have to walk
out to the outhouse, we don't have to dig a hole, if we have to go to the restroom. Data access I consider
analogous to plumbing. Almost every application needs it, but I don't have customers
coming up to me saying, "Hey, I need you to build a
data access layer for me." I have customers coming up saying, "I need an app that does this." Data access is part of that. So there's not a perceived
value add into data access. So any way we can streamline
that process to provide more functionality for the business and spending less
time on the plumbing. So I look at any Framework Core as the plumbing that
every application needs, but we don't necessarily
want to build. So in days past, and we will see demos of this, we would have to create a command
object, open a connection, write the queries somehow to
get data from the database, pull that back into
either a data set, relooking at the older technology
or a tape, tape the adapter, and read through that
data and populate models. But there's not a whole lot of
business value add to that. It's a requirement. It's a necessity. >> That's plumbing code. >> That's plumbing code. >> So the goal is always is
to spend less time writing plumbing code and more time writing the logic that's useful for
the app business logic. >> Correct. >> So that sounds like a
good overview of what it is. Let's see how it works. >> Sure. So I have some
prebuilt code here, but most of it we're
going to be typing live. So that's always
comical, but it'll work. So one thing I want
to point out before we dive into the code is there is two different paradigms that you can use with Entity Framework Core. The first paradigm, which is what a lot of people who aren't
using it will come into is, you have this existing database
and you want to start using Entity Framework Core to query the data and to work with
the data, but how does that work? Because we only have this
thing called Code-First. Code-First, in my mind, is one of the worst names that
Microsoft marketing came up with, because what we really
mean is codecentric. So in EF 6 or EF Classic, we had four ways of
talking to a database. We had with a designer
from an existing database, a designer with no database, and then what they
called Code-First with an existing database and
Code-First with no database. So I want to stress that when
we talk about Code-First, we're really talking
about codecentric. So what I have here is
a very simple project. I'm using the preview of EF Core 5, we can switch that back to 3.1, and the way we would
do that very simply is Microsoft Entity Framework
Core and the NuGet packages. We go down here to SQL Server or Microsoft Entity
Framework Core SQL Server, and we can roll back to what is
the actual supported release, and then we click on "Update." This is how you would install Entity Framework Core
into your project. You pick the version. We can also use the
command line for this. But Entity Framework
Core different than prior versions of
ORMs is very modular. So we just pull down
those bits that we need. So what I've pulled down here is
Entity Framework Core SQL Server, and then we're going
to change the version of Entity Framework Core design, which allows us to do things
like migrations and scaffolding. So this is how we set up
our original project. >> For the purposes of what we're
doing in these intro episodes, we're going to do stuff
that's in 3, 1, 3, right? >> We're going to do
stuff in 3,1. Yes. >> So there's no reason not
to use this table version. >> Yeah, the EF 5 at the time of
this recording is very early, and I don't want to confuse
people with things that might be changing as it gets farther
in the release cycle. >> Okay. >> All right. So now, we've
got our projects set up. What I want to do is I want
to take AdventureWorks, which I have installed to local DB, and I want to run a command line
interface process that will then take the existing database and create all of the Entity Framework Core objects that
I need to work with it. So this is called scaffolding. We can also do the reverse, which we'll see in a later episode, where we actually build
our database from code. But we're going to start with an
existing database and we're going to then create all of the
objects that we need, and then we'll talk about what those objects do and you'll
see examples of that. >> Does this have to be
at command line thing? Are there tools that make this easy? >> There is an add-in
that was written by, and I don't remember his name, somebody on the EF Core team, but it's not built into
Visual Studio added to box. >> Okay. >> The reason for that, and this probably
important to point out, in all of.NET Core, the command-line interface
is the queen of the root. So you can do everything
that you need to do with.NET Core and EF Core
from the command line, and you can do most of what you
need to do through Visual Studio. The reason that the
team is focusing on the command line is not
erase using Visual Studio. I could be developing this
in Visual Studio Code, or I can be using Rider by JetBrains, or I could use any host of IDEs, Notepad if I was really
not into productivity, and then do everything
from the command line. So the command line comes first
and in Visual Studio follows. >> Okay. >> All right. So if I
go to a command line, which I happen to have right here, the first thing that we have to do is install the.NET Core global tool, and I've already done this. What global tools are in .NET Core, it's similar to, if you're
familiar with the old.NET classic, putting something into the GAC, so you can access it from anywhere. To run any of the command
line tools in EF Core, we actually have to install
the global tool for EF Core. There are now tools
that were on similar to how it was done in a classic of putting things into the GAC
or the Global Assembly Cache. So it's.NET tool, we want
to install it globally. Then the tool is called dotnet-ef. Now, I already have it installed and I should probably
type in the word "install" that's what we get for it. It says it's already installed, but you're going to have
to run this command. What I'll do is I'll copy
it into this file that is coming with the show
notes right here, so we've installed the
tool that we need. Now, that we have the tool installed, we have a host of things that
we can do with the tool. So we run.NET, which is a command-line interface for
all .NET Core and we type EF. We get the magic unicorn. Then here are some of the
options that we can do. So we are going to create a DbContext in all of the pieces and parts, then this will give us a
good vehicle to talk about what the pieces and
parts of EF Core are, why they're used and
see how to use them. Now, I have pre-baked this command, It's a little lengthy. So let me clear the screen, we'll go into here, then we'll do the.NET EF, so that's the EF Core
command-line tool, I'm going to create a
DbContext and we're done. So what has this done for us? So all of AdventureWorks is now here with different
models and the DbContext. >> The DBContext is what? >> Yeah, so great segue. Thank you [inaudible]. So the DbContext is the Master Control Program if
you're a Tron fan. It's MCP. It is the heart and soul of how
Entity Framework Core works. It derives from DbContext, it contains a mechanism to tie into the database to open
connections and do things like that. It works very closely
with the change tracker which we will talk about very soon. It holds all the DbSets
which we'll also talk about. Then it has a relationship
with the database provider. So when we installed the package Microsoft.EntityFrameworkCore.SqlServer, we were adding the SQL Server data
provider into our installation. So let's talk about the pieces
and parts of the DbContext. We first have a DbSet or
a whole series of them, and these are specialized
collections that wrap our tables. Now, the way that I have built
this and the way that scaffolding works right now in 3.x is
we have table per class. So every table in the database
is represented by a DbSet. So we have address,
address type, etc. >> That's the
object-relational mapping. Because you have an address
object which is mapping to the address table in the database. >> Correct. The mapping comes in, when we look at the table itself. Now, this is just one to one, but it has a schema and a table. Now, I would typically
have called this address says in the SQL Server
side an address. So you can see that we can map our class to a table called
"foo" if we wanted to. It wouldn't be very good for
follow-up Developers, but we can. We can also change the column names. Now, these are just here
because of capitalization. So in. NET, we like to
have I lowercase d, in SQL Server, they tend to do I
uppercase D in a case sensitive. So you can see how we're mapping columns to different
columns in the database. >> So the column in the database is "StateProvinceId" and in your
class, it's called city? >> No, its attributes rolled down. So let me do this, create little space to
make it more readable. >> There we go. >> So SQL Server is
not case sensitive, unless you specify that
during the install. C-Sharp is case-sensitive.
In C-Sharp land, we don't like to have
two capitals together. >> Yeah. I see. >> The scaffolding then
changes that for us. We can also change column types. So we're specifying the SQL
Server column type of datetime, so that we are very specific
at what type of date column. Because there options in
SQL Server and we only have the datetime in C-Sharp. >> So if you wanted
to re-name a column, you would just change the
property name and the class, you wouldn't touch
that column attribute because that has to be
what's back in the database. >> Correct. I could call this "foo". >> Right. >> So let's go back
into the DbContext. This is particularly huge because of course, I've
picked AdventureWorks. Right here is how we can
figure the DbContext. Now, this is different than prior
versions of Entity Framework, but of course, this episode is
for people who haven't used it. A key tenet throughout all
of.NET Cores depends injection. So we're actually going to configure connection string and other options by injecting
them into the DbContext. So we have the full power of that. If we scroll down a bunch, we have this OnConfiguring. A lot of people brand new to
EF and EF Core will use this, I'm going to tell you don't. We're actually going to delete this. What the OnConfiguring method does is it provides a
fallback mechanism to say that if you haven't
configured this class, then we'll go ahead and
configure it for you. So what we have here as a
hard-coded connection string. So if you roll this in your production and you
forget to configure it, now you're trying to connect
to your development database. So we don't like to use this, instead of deleting it, I'll just comment it out. So that people who are looking into code can see what we
were talking about. The other thing that
the DbContext does for us is provides a mechanism
to further shape our database. This is more of that mapping. So you saw how you can
change a table names, the schema, the data type of
a column, the column name. This is where we go into much more detail of how we
want that database shaped. So for the Address entity, and we just call the
C-Sharp objects "entities" typically, in the database
provide a comment. We're now going to provide a
unique index for the RowGuid. We're also adding an index
for StateProvinceId. Here's a multi-column index. Now, we can talk about whether multi-column indexes
makes sense or not, I didn't build this database, it's just example [inaudible]. >> That's an important point though, that all of this stuff is
coming out of the database. >> Yes. So we scaffold this from the database into
our C-Sharp project. So on the flip side, if you need to add these
things into your database and you're building your model from
code when we do a migration, which is the reverse process, which we'll talk about
in a later episode. This is how you would
configure a database. The beauty of this whole process is what I call the
Homer Simpson button. So if I want to get everything
from the database into code, I just run the scaffold command
and I have everything in there. If I need to get my project, if I'm doing through Code-First, I have migrations in either
way with these commands, I have a new Developer who
starts on the project. All they have to do is run this
command-line interface with .NET CLI command and they have
everything they need. So we don't have to have a build document and all this stuff to get
Developers up and running. >> Right. >> All right, so that is
the DBContext and DbSet. Let's look a little more
about how the DBSets work. Because what I want to talk about is foreign keys and relationships. So databases and tables
have foreign keys. I wanted to go to person, because all my examples
are around persons. Here's a person object, and a person object has a foreign key out to this
thing called BusinessEntity. There's also a BusinessEntityContact that has a foreign
key back to person. So how do we represent those? We could pull to database diagram, but I'm not going to waste your time. Let's look at this first. We have this business entity, which is the one end of the many. So person is on the many end of a one-to-many relationship between
person and BusinessEntity. So from person, we have a navigation property that
goes to BusinessEntity. But we have to tell Entity Framework Core what
the foreign key value is. So we had this
BusinessEntity ID field, that's in the table, and that is the foreign key out
to the BusinessEntity table. Now, there are conventions
that I don't want to go into but, for example, based on name, structure, and other things,
Entity Framework Core will figure some of
this stuff out for you. The problem with conventions,
you have to know them. If I didn't have this here, an Entity Framework Core
would still pick up that the business entity ID is to foreign key based on
the name convention. But Robert, if you're coming
and following me in trying to understand this code and you
didn't know those conventions, you'd be like, "Well,
how does this work?" So I'm always very specific and explicit in foreign keys
on navigation properties, and thankfully, the people who built a scaffolding feel the same way. Now, inverse property just
is another helper that says, "Hey, Entity Framework Core." On the other end of this,
the BusinessEntity, we have this person
object right here. So that is the other end. That's the inverse property. We can also be on the one
end of a one-to-many, and the person in this
database example is at the one end of a one-to-many
relationship between the person table in the
BusinessEntity context. So what we get here is a collection of business entity contacts
that we can then navigate to. So these are again referred to as navigation properties on both sides. But if you think of in
terms of SQL Server, this is like saying, "Select star from person, inner join, BusinessEntityContact on BusinessEntityContact.personID
equals ID. This is how we would write to SQL
and this is how we're telling Entity Framework Core how to
join those things together. We'll see examples of how this works. >> So these properties
here are collections? >> Correct. >> Should they be pluraled? >> Yeah. >> You're [inaudible] this is a
Person.BusinessEntityContact, which then represents a collection of all the contacts for that person. >> You bring up a great point. I hate the naming
conventions that they use. So let's just real quickly talk
about how we do it in real life. So let's use the rename function. I would call this
BusinessEntityNavigation, and it's going to
refactor everything. Hopefully, this works without
breaking the example, but I have the finished product
in the oven that I might need to pull it out. So
let's talk about this. We add a property
called BusinessEntity, which is also a class. Anytime you have a property on
an object is same as a class, the same as a namespace, you start running
into name conflicts. IntelliSense tries really
hard to help you out. It will shoot you in the foot, if you have all these
names are the same. Likewise, this should be
plural. So great point. That is one thing I don't like
about out of the box scaffolding, who says you can plug in your
own code to change these rules. I didn't bother do that, that's a little complex. It's easy enough just go
in and rename things. So that's the DBSet. If we just look at the DbSet, what does the DbSet give us? It gives us in addition
to being a collection, it derives from IAsyncEnumerable,
IQueryable, etc. But we get a bunch of
methods here that help us. So we have find, here's AddRange. So we have add AddRange, update UpdateRange,
remove, RemoveRange. So these are our crud
features that we an do. So if you want to add a person, we would call context
variable.person.add, and we'll see how this works. So that's what the DbSet gives us. So last thing I want
to talk about before we were coming up against
a wall time-wise here. But the last major piece of the EF Core components
is to change tracker, and a change tracker is
what really provides the power to using
Entity Framework Core. So anytime you add data into these DBSets and you start
working with them in code, the changes are tracked, and that is used to build
very efficient queries. That's a core of Entity
Framework Core, no pun intended. >> [inaudible] worked on that one. >> All right. So I had it saved up. Next episode we're going to dive into code to show how
this stuff works. >> Great. All right. So that's a good introduction
to Entity Framework Core. Just to recap, we took
an existing database, run one line of scaffolding code after
installing some global tools, and we now have a class or object for all of the tables and all of the underlying relationships
are represented. So at this point, we'd be ready to start working with the actual data. >> Correct. >> All right, and we
will do that in Part 2, and so we will see you next
time on Visual Studio Toolbox. [MUSIC]