Show pageOld revisionsBacklinksBack to top This page is read only. You can view the source, but not change it. Ask your administrator if you think this is wrong. # IT:AD:Code First:DbContext # <callout type="Navigation" class="small"> * [[../|(UP)]] {{indexmenu>.#2|nsort tsort}} </callout> <panel title="Summary"> An EF `DbContext` is an "occasionally-connected", "in-memory" representation of the remote database. In other words, in its simplest form, a `DbContext` is rather like a `DataSet` of the whole database, keeping track of changes made to its in-mem tables, and only committing those changes back to the database when the `Commit()` method is called. </panel> ## Process ## ### Recipe ### The recipe for creating an application specific DbContext is as follows. * Create an in-app class that derives from `DbContext` (it's an `abstract` class). * Create an appropriate constructor (see: [[#About the ConnectionString/]]) * Choose an initialization strategy (see [[#About Initialization/]]) and optionally deal with Seeding concerns at the same time. * Optionally provide one or more `DbSet<TEntity>` representations of database tables. <sxh csharp> public class TestContext : DbContext { //See: http://bit.ly/t7r4pS public TestContext():base("OverrideWithCustomConnStrNameThatDiffersFromExpectedTestContex") {} public DbSet<TestEntity> TestEntities { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { //Keep tables as TestEntity -- not TestEntities modelBuilder.Conventions.Remove<PluralizingTableNameConvention>(); //modelBuilder.Entity<TEstEntity>() // .HasRequired(a => a.Source) // .WithMany() // .HasForeignKey(a => a.SourceId); } } </sxh> ### About the ConnectionString ### As stated above, the most common common convention is to provide an argument-less constructor (note that an argumentless constructor is required for Code migrations from a [[IT/AD/Continuous Integration/]] point of view). The reasoning behind this is that by default the `DbContext` finds its connection string by adhering to the [[IT/AD/Design/Patterns#Convention over Configuration/]] pattern: <sxh xml> <add name="ConnStrName" connectionString="Data Source=.;Initial Catalog=SomeDb;Integrated Security=True" providerName="System.Data.SqlClient" /> </sxh> Note that it actually looks for the best solution in several places: http://bit.ly/t7r4pS <WRAP tip> For those who have a need to go beyond *Convention* (really?), one can override the *ConnectionString* with a custom name (see below) or passing a specific ConnectionString (it will tell the difference by the fact that *ConnectionString*'s have a '=' in them somewhere. But before breaking Conventions, consider that they they are there for a reason. For one, they're cheaper to maintain among a team. </WRAP> ### About Initialization ### The first call to the DbContext implementation during the lifespan of the application will invoke the [[IT/AD/Code First/DbContext/Initialization|IDatabaseInitializer]] associated to the database. There are various [[IT/AD/Code First/DbContext/Initialization|IDatabaseInitializer]], but I think they all check to see if the database schema has changed before proceeding. They do this by querying the schema from the database, and comparing this against an in-mem map of what your code says the database is. You provide the in-mem description of the map within the `OnModelCreating` event handler. Depending on the flavour of the [[IT/AD/Code First/DbContext/Initialization|IDatabaseInitializer]] invoked, if the two don't match, it may decide to upgrade the db, using the model you provided within the `OnModelCreating` event handler. The Model is built up using [[IT/AD/Code First/FluentAPI/]] syntax. Once the model check within the [[IT/AD/Code First/DbContext/Initialization|IDatabaseInitializer]] stage is out of the way (it's only relevant for the first call of an app), you refer to Database tables by exposing DbSet<T> properties of those entities (exposing entities that are not described within the `OnModelCreating` event handler will obviously create an error). ### Notes ### Note that unlike *ModelFirst* or *DatabaseFirst* (which expect [EntityConnection](http://bit.ly/uPULxy)), *CodeFirst* expects just a *ConnectionString*. /home/skysigal/public_html/data/pages/it/ad/code_first/dbcontext.txt Last modified: 2023/11/04 03:22by 127.0.0.1