I am trying to use EF Core code first migrations to de-normalise an existing table.
I have en existing table LoginEvent which data looks like this:
╔═════════════════════════════════════════════════╗
║ LoginEvent ║
╠════╦══════════╦═══════════╦════════════╦════════╣
║ Id ║ VenueRef ║ VenueName ║ OccurredAt ║ UserId ║
╠════╬══════════╬═══════════╬════════════╬════════╣
║ 1 ║ ven01 ║ Venue 1 ║ 2018-01-29 ║ 5 ║
╠════╬══════════╬═══════════╬════════════╬════════╣
║ 2 ║ ven02 ║ Venue 2 ║ 2018-01-30 ║ 7 ║
╠════╬══════════╬═══════════╬════════════╬════════╣
║ 3 ║ ven01 ║ Venue 1 ║ 2018-02-01 ║ 9 ║
╚════╩══════════╩═══════════╩════════════╩════════╝
public class LoginEvent
{
[Key]
public int Id { get; set; }
public string VenueRef { get; set; }
public string VenueName { get; set; }
public DateTime OccurredAt { get; set; }
public User User { get; set; }
}
And I want to normalise this into two tables: LoginEvent and Venue, like so:
╔═════════════════════════════════════╗
║ LoginEvent ║
╠════╦══════════╦════════════╦════════╣
║ Id ║ VenueRef ║ OccurredAt ║ UserId ║
╠════╬══════════╬════════════╬════════╣
║ 1 ║ ven01 ║ 2018-01-29 ║ 5 ║
╠════╬══════════╬════════════╬════════╣
║ 2 ║ ven02 ║ 2018-01-30 ║ 7 ║
╠════╬══════════╬════════════╬════════╣
║ 3 ║ ven01 ║ 2018-02-01 ║ 9 ║
╚════╩══════════╩════════════╩════════╝
╔══════════════════════╗
║ Venue ║
╠══════════╦═══════════╣
║ VenueRef ║ VenueName ║
╠══════════╬═══════════╣
║ ven01 ║ Venue 1 ║
╠══════════╬═══════════╣
║ ven02 ║ Venue 2 ║
╚══════════╩═══════════╝
Now, I have done this by adding a new Venue domain object and having the LoginEvent reference it, like so:
public class LoginEvent
{
[Key]
public int Id { get; set; }
public string VenueRef { get; set; }
public DateTime OccurredAt { get; set; }
public Venue Venue { get; set; }
public User User { get; set; }
}
public class Venue
{
[Key]
public string VenueRef { get; set; }
public string VenueName { get; set; }
}
I've then created a migration, which (correctly):
Venue tableVenueName columnHowever, what I need to be able to do is run a data migration between steps 1 and 2 so that the existing Venues are in the new table before dropping the column and before setting up the constraint (otherwise, I'll lose data and the constraint fails as I don't have associated Venues).
I'd like to run something like this as my data migration:
INSERT INTO Venue SELECT DISTINCT VenueRef, VenueName FROM LoginEvent
How should I do this?
You can execute any SQL using migrationBuilder.Sql(theSqlString).
In your case
migrationBuilder.Sql("INSERT INTO Venue SELECT DISTINCT VenueRef, VenueName FROM LoginEvent");
Run this in the migration after creating the new table Venue and before dropping the old column VenueName.
See also Custom Migrations Operations.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With