In previous post Entity Framework Code First Basic FAQ – Part 1, I discuss some frequently asked questions when I start working with Entity Framework Code First. This post will follow the spirit of the previous one, some interesting points of Entity Framework will be demonstrated in short code listings. In source code sample, you’ll find 2 projects, the project numbered with number 2 is for this post.
1. Multiple contexts with same connection
The Entity Framework allows us to use multiple DbContext on same connection, we just need to use the same connection string in the constructors. For example, the following TeacherContext and CourseraContext use same DefaultConnection
public TeacherContext() : base("DefaultConnection") { } public CourseraContext() : base("DefaultConnection") { }
2. Migrations for multiple DbContext
When we use multiple DbContext in our solution and we would like to use Migration for some of them, then we can enable Migration separately for each DbContext as following
Enable-Migrations -ContextTypeName:EF_CodeFirst_Basic_2.Entities.CourseraContext -MigrationsDirectory:CourseraMigrations Enable-Migrations -ContextTypeName:EF_CodeFirst_Basic_2.Entities.TeacherContext -MigrationsDirectory:TeacherMigrations
In the example above, I enable Migration for our 2 DbContext: TeacherContext and CourseraContext. The Migration steps will be generated under separated directories. Just note that if you have multiple DbContext, the InitialCreate migration maybe won’t be automatically created. In that case, use following commands to generate it.
Add-Migration -Configuration EF_CodeFirst_Basic_2.CourseraMigrations.Configuration InitialCreate Add-Migration -Configuration EF_CodeFirst_Basic_2.TeacherMigrations.Configuration InitialCreate
3. Fluent API mapping with available database
If we have a not well-formed database in use and we would like to use EntityFramework Code First for accessing data. We couldn’t use the default settings of EntityFramework because the naming convention doesn’t work, then let’s use the Fluent API. For example, in code listing below, I map the CourseraContext manually with Fluent API.
internal class CourseraContext : DbContext { public CourseraContext() : base("DefaultConnection") { } public DbSet<Course> Courses { get; set; } public DbSet<Student> Students { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Configurations.Add(new CourseMap()); modelBuilder.Configurations.Add(new StudentMap()); base.OnModelCreating(modelBuilder); } } internal class CourseMap : EntityTypeConfiguration<Course> { public CourseMap() { this.ToTable("Course"); this.HasKey(x => x.Id); this.Property(x => x.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); this.Property(x => x.Id).IsRequired(); this.Property(x => x.Name).IsRequired(); this.Property(x => x.Url).IsOptional(); } } internal class StudentMap : EntityTypeConfiguration<Student> { public StudentMap() { this.ToTable("Student"); this.HasKey(x => x.Id); this.Property(x => x.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); this.Property(x => x.Id).IsRequired(); this.HasRequired(x => x.Course).WithMany(x => x.Students).HasForeignKey(x => x.CourseId); this.Property(x => x.FirstName).IsRequired(); this.Property(x => x.LastName).IsRequired(); } }
We can set many options such as null-optional, primary key, foreign key,column name… The Fluent API mapping brings big advantage when refactoring code. You can rename the property of data object as you want, the column name in database wouldn’t have to be changed . Or if there is any change from database, for example column renaming, you don’t have to change the name of the property, you only need to change the column name in mapping code.
4. Source code
Source code: https://bitbucket.org/hintdesk/dotnet-entity-framework-code-first-basic-faq