EntityFramework Core Migration (Code First) — Part I: Entity Models

Chewy2Theo
3 min readMay 29, 2021

--

One to Many Configurations

This is what the code looked like in .Net. I used to quite liked fluent API and favored it over annotations, but after the migration I think annotation would save a lot of time if you had that in your old code base.

This is what it looks like in .Net Core. I believe the code looks much cleaner and easier to understand when annotations are used as much as possible. But if you still prefer to use fluent API for the configuration, you can refer to the one to many foreign key shown below.

And you can apply the EntityConfiguration as shown below:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new Address.Mapper());
}

One to One Configuration

Creating One to One mapping in .Net is easy. With the example below Attendee and Account has a One to One Optional relationship, meaning Attendee is the primary table and has an optional Account linked to it.

On the Attendee Table side, it just needs to declare a virtual Account.

public virtual Account Account { get; set; }

But now with .Net Core things are more complicated. I did not find a way to declare this relationship within the EntityConfiguration, instead I have to go to the DbContext’s onModelCreating method and declare this code below.

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Attendee>()
.HasOne<Account>(x => x.Account)
.WithOne(x => x.Attendee)
.HasForeignKey<Account>(x => x.Id)
.IsRequired(false);
}

The Attendee Part stays the same and this is what the Account code would look like.

Many To Many Configuration

And Now we come to the most troublesome of all — many to many. But it was partially my fault due to bad practice in .Net code. Below is how I declared the many to many relationship in .Net

What’s so bad about the above configuration? The Table name. The convention should’ve been AccountRoles but due to poor naming standard the code above named it as AccountToRole. This makes things complicated for me and I had to spend quite a bit of time before I could find a proper solution to keep this poor naming that I had, otherwise I’ll need to create SSIS tasks and pour the data over, which would then create a huge hassle.

First create Many to Many Relationship Table (Optional)

namespace Data.Entities
{
public partial class AccountToRole
{
public AccountToRole()
{
}
public int AccountId { get; set; }
public virtual Account Account { get; set; }
public int RoleId { get; set; }
public virtual Role Role { get; set; }
}
}

Then declare the Many to Many Relationship Table in both Account Class and Role Class

public virtual ICollection<AccountToRole> AccountToRoles { get; set; }

Finally apply the below configuration within your DbContext’s onModelCreating method

modelBuilder.Entity<Account>()
.HasMany(p => p.Roles)
.WithMany(p => p.Accounts)
.UsingEntity<AccountToRole>(
j => j.HasOne(pt => pt.Role)
.WithMany(t => t.AccountToRoles)
.HasForeignKey(pt => pt.RoleId),
j => j.HasOne(pt => pt.Account)
.WithMany(p => p.AccountToRoles)
.HasForeignKey(pt => pt.AccountId),
j => { j.HasKey(t => new { t.AccountId, t.RoleId }); });

If you configure the many to many relationship with the above example you should be able to reuse the many to many tables that you already are using and EF Core will not create additional tables for you.

If you already have proper naming conventions in your .Net code, you can then follow one of the guides below, which will save you quite a bit of trouble:

If you’re curious as to what changed from EF to EF core, you can refer to this doc here:

This article is a part of the .Net to .Net Core Migration Series
https://theochiu2010.medium.com/net-to-net-core-migration-2eb31584f95c

Sign up to discover human stories that deepen your understanding of the world.

--

--

Chewy2Theo
Chewy2Theo

Written by Chewy2Theo

Just another developer who's into lazy tools that can make my life easier, and hopefully yours too.

No responses yet

Write a response