Objective
In the previous article, we talked briefly about how to migrate in EF Core1.1, and in this article we'll talk about the things that are not known in EF Core1.1, and take the details from me.
Explicitly creating an DbContext instance through a constructor with onconfiguring
This is supposed to be our simplest way, by calling a class that inherits from DbContext and calling its parameterless constructor, and we need to remember that whenever we instantiate it we need to release it, which is to wrap its instance in the using. As follows:
using (varnew Efcorecontext ()) {}
The EF core Context instance is then configured by overloading Onconfiguring, as follows.
Public class efcorecontext:dbcontext{ protectedoverridevoid onconfiguring ( Dbcontextoptionsbuilder optionsbuilder) = Optionsbuilder.usesqlserver (@ "server=.;D Atabase=eftest; Trusted_connection=true; " );}
Note: overloaded onconfiguring is not the same as the onmodelcreating creation model in the previous EF version, Onmodelcreating creates a model context that is instantiated only once, But Onconfiguring is called once every time a context is instantiated, so onconfiguring can take full advantage of the constructor or other data in the context.
In EF 6.x there are many constructors for contexts, such as connection string parameters, which are also available in EF Core 1.1:
Public class efcorecontext:dbcontext{ privatereadonlystring _connectionstring; Public Efcorecontext (string connectionString) { = connectionString; } protected Override void onconfiguring (dbcontextoptionsbuilder optionsbuilder) = = Optionsbuilder.usesqlserver (_connectionstring);}
Using Dbcontextoptions with no dependency injection
In DbContext's constructor we can accept a Dbcontextoptions object, which is used primarily when creating an DbContext instance in a Di container, and of course it can be explicitly called, By creating a Dbcontextoptions object to be isolated from the context, it can use the same options for each instance of the context, as follows:
Publicclass efcorecontext:dbcontext { public Efcorecontext ( Dbcontextoptions options) base(options) { } }
public class Homecontroller:controller { private static dbcontextoptions _contextoptions;
public Iactionresult Index () {_contextoptions = new Dbcontextoptionsbuilder (). Usesqlserver (""). Options; using (var context = new Efcorecontext (_contextoptions)) {} return View (); } }
Seeing here we see that there is no need to reload onconfiguring, but onconfiguring will still be overloaded and called, why so Because we inject the context into the configuration, it calls the constructor and simultaneously makes the appropriate adjustments to the onconfiguring.
Creating an DbContext instance using dependency Injection
We just register the context type in the Di container, and then it will be parsed by the DI container, but the context is registered in the DI container and we don't have to worry about it, you have to notice the following two points. We typically inject it into the DI container to do so.
Public class Efcorecontext:dbcontext { public efcorecontext (dbcontextoptions options) base(options) { } }
Services. adddbcontext<efcorecontext> (options = = = d.migrationsassembly (" Studyefcore"); });
reasonable and lawful, but why not use the following
Services. Addsingleton<efcorecontext> ();
Is it not possible to inject in a single case, if you do, you wait for the program to crash, because the context dbcontext is not thread-safe, that is, it cannot be registered to a singleton to use no extra locks. And then after injecting it into the Di container, when we use it or use it to wrap it, you don't think it's going to be injected into the DI container. It does everything for you, the DI container does not automatically handle for you, of course, if you are only temporarily used in the Di container, it is usually not a disaster. So we need to remember the following two points.
(1) When the context is injected into the DI container, the use of DbContext is still included, as the Di container does not automatically release it.
(2) DbContext is non-thread-safe, even in the Di container, there is nothing to ensure that there is no problem, most of the situation is not problematic, do not worry .
Di with dbcontextoptions create DbContext instance
Whether we register a dbcontextoptions instance in Di is still a bit of a use, it will only be created once and used as a singleton. For example, we can initialize the data, as follows
Public class Efcorecontext:dbcontext { public efcorecontext (dbcontextoptions options) base(options) { } }
Private Static IServiceProvider _serviceprovider; Public iactionresult Index () { var contextoptions = new Dbcontextoptionsbuilder () . Usesqlserver ("") . Options; var services = new Servicecollection () . Addsingleton (contextoptions) . Addscoped<efcorecontext> (); _serviceprovider = Services. Buildserviceprovider (); return View (); }
Now the Efcorecontext context will be parsed by the DI container, and the Dbcontextoptions instance will be injected into its constructor. This _serviceprovider is the provider of the injection context, and we have said that we can initialize the data, how to initialize the Nikki, let's see. The following configuration methods are used in Startup.cs:
Public void Configure (Iapplicationbuilder app, Ihostingenvironment env, iloggerfactory loggerfactory) { .... }
The app has the following properties:
Discover what no, this is the abstract attribute of all injected services, we convert it to Efcorecontext to initialize the data in this method, let's see.
Private Static efcorecontext context; Public Static void Initialize (IServiceProvider serviceprovider) { = (efcorecontext) serviceprovider.getservice (typeof(Efcorecontext)); // Do your something }
Creating DbContext instances using generic dbcontextoptions
All of the above-described Dbcontextoptions objects are non-generic, as follows:
Public class Efcorecontext:dbcontext { publicefcorecontext (dbcontextoptions options): Base (Options) {} protected Overridevoid onmodelcreating (ModelBuilder ModelBuilder) { Modelbuilder.addentityconfigurationsfromassembly (GetType (). GetTypeInfo (). Assembly); } }
But there is a generic version of the dbcontextoptions in its parameters, so what the generics are for, let's look at the following example:
Public classEfcorecontext1:dbcontext { PublicEfcorecontext1text1 (dbcontextoptions<efcorecontext1>options):Base(Options) {}} Public classEfcorecontext2:dbcontext { PublicEFCORECONTEXT2 (dbcontextoptions<efcorecontext2>options):Base(Options) {}}varCONTEXTOPTIONS1 =NewDbcontextoptionsbuilder<efcorecontext1>() . Usesqlserver (CONNECTIONSTRING1). Options; varContextOptions2 =NewDbcontextoptionsbuilder<efcorecontext2>() . Usesqlserver (connectionString2). Options; varServices =Newservicecollection (). Addsingleton (CONTEXTOPTIONS1). addscoped<EFCoreContext1>() . Addsingleton (CONTEXTOPTIONS2). addscoped<EFCoreContext2>(); _serviceprovider= Services. Buildserviceprovider ();
See what no, if there are multiple context types registered in the DI container, we can allow each context type to depend on its own options. When parsing EFCoreContext1 will cause dbcontextoptions<efcorecontext1> to be injected, and parsing EFCoreContext2 with due cause dbcontextoptions< Efcorecontext2> will be injected.
Use Adddbcontext to create DbContext instances
Register DbContext and Dbcontextoptions instances by adddbcontext syntax sugar. As follows:
var New servicecollection () . Adddbcontext<EFCoreContext>( = B.usesqlserver (connectionString));
By default, Efcorecontext is registered as scope, and Dbcontextoptions is registered as a singleton, and you can change the Efcorecontext as a singleton registration, which we have already discussed. Okay, here we are. Presumably we know several ways to create an EF core context instance, which we summarize as the following three points.
(1) Call the context constructor directly and overload onconfiguring to create the context instance.
(2) Pass dbcontextoptions to the constructor to create the context instance.
(3) Create a context instance from the Di container.
Use Dbcontextoptionsbuilder to configure a dbcontext and eventually construct a Dbcontextoptions object, This can also be passed to the DbContext constructor by overloading the Onconfiguring method or by constructing the options, whether through a parameterless constructor or through dbcontextoptions to the context's constructor, or by injecting the dbcontext into the DI container is the same, there is no essential difference, but through di simple and forced lattice relatively high, no other.
Summarize
Well, in this section we have already described several ways to create context in EF Core 1.1, have you already understand it, goodnight, the world, and stay up late.
How does entityframework Core 1.1 create an DbContext instance?