Entity Framework Code First Basic FAQ – Part 2

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

Migrations for multiple DbContext

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

Leave a Reply

Your email address will not be published. Required fields are marked *