 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 DB context. Hi, welcome to Visual Studio Toolbox. I'm your host, Robert Green, and joining me today is Phil Jepixi. 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 DB context. A big change between EF core and EF classic, for lack of a better term, is how we set up the DB context. It is there's a lot more involved, which is actually a good thing. With EF6, when you created a DB context type, you didn't have a whole lot of options. With EF core, you have all the options. They went the other direction, and what comes out of the box is nothing, and you have to opt into everything, including which database provider you want to use. 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 civic features of EF core in general. Cool. Let's start with what packages do you need? 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 it which NuGet package we want to use for a database provider. We pull in Microsoft entity framework core.SQL server, that will bring in Microsoft entity framework core and some other sub-packages, but we actually specifically tell it what database provider to use. There are a ton of them out there. As you go through your configuration process, let's pull up the GUI here and browse for, it should be in my dropdown, Microsoft entity framework core, and 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 light, and these are just the ones that are right out of the box. There's also providers for Cosmos, third-party providers for things like MySQL, and Oracle, and those types of things. There's a ton of options which really is good, except if you want to just sit down and push the Home or Simpson button and everything set up, then I guess it might not be so good for you, but that was the way EF6 worked is you had the big button on the nuclear power reactor that Homer Simpson would just push the button, knows his whole job, and you got everything. This new paradigm minimizes the install, minimize what you have to load, but does make you do a little bit of work. Let's look at the context, and we were using, now we teach you a little bit by configuring batching in the last episode, sorry, our first episode of this series. We talked about this briefly in our overview series, the on-configuring, and one of the first things that I do if I scaffold something as I go ahead and delete this. This is a fallback. You see that it's taking a text options builder, and that is a mechanism we use to build up all the options we want to select for a particular derived DB context class. This on-configuring event is raised as a DB context is created, an instance of it, and 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 path somewhere where we forget to configure the DB context, our derived DB context, and then it's going to default to local DB. In real-world development, I would delete that. The next thing we do is we look at how we build up a DB context in code. At a bare minimum, what we want to do is have a connection string and that is provider-specific. Probably don't want to be using trust 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 local DB, but I have to tell it what database provider to use. Here I am saying use SQL Server, and that's the only one I have any options because I haven't installed any other NuGet packages for other providers. In this case, I'm saying use SQL Server and I'm passing in the connection string. That's a bare minimum. Now, there's two additional things we can configure on every instance of our DB context class. There are provider-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 NED framework itself. When we look at, let me just duplicate this, so we have something to play with. I have some examples down here, but use SQL Server then takes a builder. 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. Enable retry on failure. This out of the box gives you an 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 your own, then it will automatically retry a certain number of times with the expanding delay. The defaults changed a couple of times. I think it's five tries, starting at 100 milliseconds of expanding. Don't quote me on that even though we are on video, so somebody will comment, but that was what the options were with defaults. 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. If we want to set the command timeout to 100, we have now configured the SQL Server provider. You can also configure entity framework itself, and the way we do that is outside of the options for SQL Server for your Davis provider. 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 enable sensitive data logging, not what you want to do in production, but this will 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, you use a specific query tracking behavior, this is default, track all, but I can say, you know what, I don't ever want to add anything into the change tracker, unless I tell it otherwise. Defeats purpose using an ORM, but these are all the settings you can do. Okay, cool. There's a whole lot that we can set. We will just know one of these as we go through different shows. But now I want to talk about the design time DB context 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 I design time DB context factor is provided by Entity Framework Core? That is correct. Okay. So when you were running command line options, the EF Core command line tooling is looking for something that derives from DB context. If it finds something that derives from DB context, it wants to have, it needs to be configured and it needs a default constructor. So it gets a little, we'll just use a technical term, it gets squirrely if you're using the command line functions for things like creating migrations, updating migrations, those types of things, and you're doing it right against your production file. In this case, our AdventureWorks 2016 context. The design time DB context factory 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 in the design time DB context factory to be local DB. 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, whenever we're 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 DB context factory, the design time DB context factory. That's a database that's going to drop. It's not going to reach into my configuration system and say, oh, you want to drop production. Sure, we can do that. Dash F for force. Yep, it's gone. These ARGs here, they're placeholders. They have been placeholders in the beginning, and they're still placeholders. They reserve the right to use them in the future. Sorry, I had to take a drink, but they're not being used now. Then what we do is we just return the 2016 context, our context using these options. Now that we have this builder, let's talk more about how we use this in production. You saw snippets of this. Down here, let's go into this method with the no batching and we'll pull this up. Because the on configuring is turned on, I can use a call like this. Now, it 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, we talked the last episode about some user 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 DB context options builder, pass that in and get a single use separately configured DB context for that particular need and when you leave the using block or the using statement, if you use the new C sharp using statement, then there's DB context options go away. Any questions? Nope. 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 get to use SQL Server, use MySQL, use Oracle. You don't get them all out of the box. When you have six 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 design time tooling, you have to pull in any framework core.design. That gives you access to using the COI to DB context factory. You can also pull in Microsoft.anyframeworkcore.tools, and that will allow you to use package manager console to, let me clear that, package manager console to do things like run migrations. It's just a little different syntax. One is using the package manager and new get syntax. The other one is using the .NET Core command line interface. Okay. Got it. That's what I wanted to just call out about configuration and using the design time DB context factory. 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. All right. I hope you guys enjoyed that, and we will see you next time on Visual Studio Toolbox.