>> On today's Visual Studio Toolbox,
we continue our series on Entity Framework Core and Phil
is going to show us how to configure the DbContext.
[MUSIC]
>> Hi, welcome to Visual Studio Toolbox.
I'm your host, Robert Green,
and joining me today is Phil Japikse. Hey, Phil.
>> Hey, Robert.
>> Today is part three of
our second series on Entity Framework Core,
and today we're going to talk about configuring the DbContext.
>> Yeah. So a big change between EF Core and EF Classic,
for lack of a better term,
is how we set up the DbContext.
There's a lot more involved,
which is actually a good thing.
So with EF6, when you created a DbContext type,
you didn't have a whole lot of options.
With EF Core, you have all the options.
So they went the other
direction and what comes out of the box is nothing,
and you have to opt-in to everything,
including which database provider you want to use.
So I want to get that covered.
There's a ton of options that you can configure.
We're going to cover some of them today.
Other ones that we're going to talk about later
in this series as we talk about
specific features of EF Core, in general.
>> Cool.
>> So let's start with what packages do you need,
and one thing that is specific to EF Core,
well, all of .NET Core.
But if we look at EF Core,
we actually have to tell
which NuGet package we want to use for a database provider.
So we pull in Microsoft.EntityFrameworkCore.SQLServer,
that will bring in Microsoft Entity Framework Core
and some other sub-packages.
But we actually, specifically tell
what database provider to
use and there are a ton of them out there.
So as you go through your configuration process,
go up to the GUI here and browse for,
It should be a my dropdown,
MicrosoftEntityFrameworkCore.
We see we have SQL Server, we have in-memory,
which is typically used for integration testing.
But I will tell you it's being de-emphasized in EF Core five,
SQL lite, and these are just the ones that
are right out of the box. There's providers for Cosmos,
third-party providers for things like MySQL,
and Oracle, and those types of things.
So there's a ton of options,
which really is good,
except if you want to just sit down
and push the Homer Simpson button and everything is set up,
then I guess it might not be so good for you.
But that was good way EF6 worked,
is you had the big button on
nuclear power reactor that
Homer Simpson would just push the button,
that was his whole job, and you got everything.
Just new paradigm minimizes the install,
minimizes what you have to load,
but does make you do a little bit [inaudible] .
>> Okay.
>>So let's look at the context itself,
and we teased you, a little bit, by configuring
batching in our first episode of this series.
We talked about this briefly in our overview series OnConfiguring.
One of the first things that I do,
if I scaffolds something as I go ahead and delete this.
This is a fall back.
You see that it's taking in DB text options builder,
and that is the mechanism we use to build up all the options we
want to select for a particular derived DbContext class.
This OnConfiguring event is,
as a DbContext, is created, an instance of it.
Then if it's not configured,
you can put in a default configuration right here.
There's nothing technically wrong with doing that,
except for the fact that
it makes me nervous that there might be some code paths
somewhere where we forget to configure
the DbContext or derive DbContext,
and then it's going to default to local DB.
So in real-world development,
I would delete that.
The next thing we do is we look at how
we build up a DbContext in code.
So at a bare minimum,
what we want to do is have
a connection string and that is provider-specific.
You probably don't want to
be using trusted connection equals true.
You want to use something like Azure Key Vault,
or active directory, or something to lock down your security.
Again, this is a development machine going against the local DB.
But I have to tell it what database provider to use.
So here I am saying use
SQL Server and that's the only one I have in
the options because I haven't installed
any other NuGet packages for other providers.
So in this case, I'm saying use SQL Server and I'm
passing in the connection string. That's the bare minimum.
Now, there's two additional things we can
configure on every instance of our DB context class.
There are providers specific options that we can do, and
there's also holistic options that we
can set that runs outside of the provider space,
but helps to configure Entity Framework, itself.
So when we look at,
let me just duplicate this so we have some time to play with,
and I have some examples down here.
But UseSQLServer then takes a builder.
So we have an options builder,
so that is represented by a Lambda,
and then now we have options specific
to the SQL Server provider that we can then set.
So enable retry on failure.
This, out of the box,
gives you that execution strategy that says, if
there is a transient error, we'll just turn that on,
a transient error in your call,
and transient errors are defined by the SQL Server team,
although you can configure it your own,
then it'll automatically retry
a certain number of times with an expanding delay.
The default changes a couple of times.
I think it's five tries,
starting at 100 milliseconds and expanding.
Don't quote me on that,
even though we're on video.
So somebody will comment.
But that was what the options were, defaults.
So now we've just turned on automatic retry.
We can also change things like the command timeout,
the max batch size,
which we showed you in that first episode,
the min batch size,
and these are SQL Server provider specific things.
So if we want to set the command timeout to
a hundred, we have now configured the SQL Server provider.
>>Okay.
>> We can also configure Entity Framework, itself.
The way we do that is outside of
the options for SQL Server or your data provider,
so I'll make that a one-line so we know we're somewhere different.
Now I'm back on
the Options Builder and I can EnableSensitiveDataLogging.
Not what you want to do in production,
but then if there's an error thrown,
it'll say, for example,
"Foreign key exception",
but it's not going to give you any of that data.
So you can turn this feature on to get that data in
your logs and we're going to
talk more about how you turn it on and off.
So this is great for debugging,
not so good for production.
If I want everything to always,
unless I specify, otherwise,
use a specific QueryTrackingBehavior,
this is default, TrackAll,
but I can't say, you know what?
I don't ever want to add anything into the Change Tracker,
unless I tell it, otherwise.
Defeats the purpose using an ORM,
but these are all the settings you can do.
>> Cool.
>> But there's a whole lot that we can set,
we'll review additional ones of these as
we go through different shows.
But now I want to talk about
the DesignTimeDbContext Factory and
then we'll wrap up by how we use these things in code,
and why this is such a benefit over
the default way of configuring in EF6.
>> So that iDesignTimeDbContextFactory
is provided by Entity Framework Core?
>> That is correct.
>> Okay.
>> When you are running command line options,
the EF Core command line tooling is looking
for something that derives from DbContext.
If it finds something that derives from DbContext,
it needs to be configured and it needs a default constructor.
We'll just use a technical term,
it gets squirrely, if you're using
the command line functions for things like
creating migrations up to the migrations,
those types of things, and you're doing
it right against your production file,
in this case, our Adventure Works 2016 context.
The DesignTimeDbContextFactory is only used by the tooling.
It will never be used by your production code,
unless you specifically reach out and call it.
This allows us to then
hard-code a connection string if we so choose.
We can also use the .NET Core
Configuration System to then pull that in.
But typically, we will hard-code the connection string
into DesignTimeDBContextFactory to be LocalDB,
because that's where we're doing our local development,
and then, be able to do all of
our local things we
need knowing that we're never hitting production,
we're never hitting staging,
we're never doing these other things,
and have that isolation,
that, hey, we know we're in a development environment.
I'm doing a command line tool that says drop database.
I know it's going to look for this DesignTimeDbContextFactory.
The database is just going to drop.
It's not going to reach into my configuration system
and say, "You want to drop production?
Sure, we can do that. -F for force? Yeah, it's gone."
These args here, they're placeholders.
They have been placeholders from
the beginning and they're still placeholders.
They reserve the right to use them in the future,
but you're not being used now.
Then what we do is we just return
the 2016 contexts, using these options.
So now that we have this builder,
let's talk more about how we use this in production.
You saw snippets of this.
So down here, let's go into
this method with the no batching and it will pull this up.
Because the OnConfiguring is turned on,
I can use a call like this.
Now, this should be injected in through dependency injection.
That's how you do it in ASP.NET Core for sure,
it's also how we do it in all of our .NET Core applications.
Again, this is demo code.
We're not building in
the full IOC container to keep this sample simple.
But here's an [inaudible] we talked last episode
about using query types for
changing things around based on a certain call.
You find that the batch size is not
working for this particular query that you want to use.
You can then create a new DbContext options builder,
pass that in, and get a single use, separately
configured DbContext for that particular need,
and when you leave the using block or the using statement,
if you're using the new C Sharp using statement,
then those DbContext options go away.
So any questions?
>> No.
>> Okay.
>> I think it's pretty straightforward.
>> It's very straightforward.
I just want to call out that depending
on which packages you download for database providers,
you're going to UseSQLServer,
UseMySQL, UseOracle.
You don't get them out of the box.
With EF6, when you install it,
you get this huge installation and everything's built in.
You have to call out specifically which ones you want to use.
Then if you want to use the DesignTime tooling,
you have to pull in EntityFrameworkCore.Design, that gives you
access to using the CLI to DbContextFactory.
You can also pull in Microsoft.EntityFrameworkCore.Tools
and that will allow you to use Package Manager
console to do things like run migrations.
It's just a little different syntax.
One is using other package manager,
NuGet Syntax, the other one is
using the .NET Core Command Line Interface.
>> Okay. Got it.
>> So that's what I wanted to just call out about configuration
and using the DesignTimeDbContextFactory.
>> Right on. Cool. Nice short episode,
that's a rarity for us.
>> Yeah. We had some time debt we had to pay back, so there we go.
>> There you go. I hope you guys enjoyed that,
and we will see you next time on Visual Studio Toolbox.
[MUSIC]