Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EF Core Updates Seeded Data on every Migration without being changed

So I'm seeding my databse with Users and Roles like this.

public static void SeedUsers(this ModelBuilder modelBuilder)
    {
        var roles = new[]
        {
            new Role
            {
                Id = new Guid("5127599a-e956-4f5e-9385-1b8c6a74e4f1"),
                RoleName = "Customer"
            },
            new Role
            {
                Id = new Guid("8634c476-20fa-4391-b8f7-8713abf61af0"),
                RoleName = "Admin"
            }
        };

        // customer password
        byte[] customerPasswordHash = null;
        byte[] customerPasswordSalt = null;
        HashPassword("asd123", out customerPasswordHash, out customerPasswordSalt);

        // admin password
        byte[] adminPasswordHash = null;
        byte[] adminPasswordSalt = null;
        HashPassword("asd123", out adminPasswordHash, out adminPasswordSalt);
        var users = new[]
        {
            new Users()
            {
                Id = new Guid("3b86f5a2-1978-46e3-a0b6-edbb6b558efc"),
                FirstName = "John",
                LastName = "Doe",
                DepositedCash = 10000,
                Email = "[email protected]",
                RoleId = roles[0].Id,
                PasswordHash = customerPasswordHash,
                PasswordSalt = customerPasswordSalt
            },
            new Users()
            {
                Id = new Guid("c643b944-53d9-4a0c-9922-3486558b9129"),
                FirstName = "Admin",
                LastName = "Admin",
                DepositedCash = 10000,
                Email = "[email protected]",
                RoleId = roles[1].Id,
                PasswordHash = adminPasswordHash,
                PasswordSalt = adminPasswordSalt
            }
        };

        modelBuilder.Entity<Role>()
            .HasData(roles);

        modelBuilder.Entity<Users>()
            .HasData(users);
    }

    private static void HashPassword(string password, out byte[] passwordHash, out byte[] passwordSalt)
    {
        using (var hmac = new System.Security.Cryptography.HMACSHA512(Encoding.UTF8.GetBytes("predefined key")))
        {
            passwordSalt = hmac.Key;
            passwordHash = hmac.ComputeHash(Encoding.UTF8.GetBytes(password));
        }
    }

I'm creating a migration and Update the database. So far so good.

After that when I create another test migration, without changing anything it creates an UpdateData method with the same data. Everything in Up and Down methods is the same.

using System;
using Microsoft.EntityFrameworkCore.Migrations;

namespace Pizzeria.Data.Migrations
{
public partial class test : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.UpdateData(
            table: "Users",
            keyColumn: "Id",
            keyValue: new Guid("3b86f5a2-1978-46e3-a0b6-edbb6b558efc"),
            columns: new[] { "PasswordHash", "PasswordSalt" },
            values: new object[] { new byte[] { 211, 141, 232, 166, 77, 237, 128, 211, 121, 45, 47, 68, 211, 202, 162, 3, 39, 214, 212, 153, 4, 199, 223, 213, 43, 233, 224, 21, 107, 10, 62, 220, 105, 27, 254, 137, 16, 208, 56, 42, 254, 211, 154, 27, 60, 135, 197, 224, 148, 99, 232, 246, 220, 121, 113, 103, 42, 117, 172, 240, 134, 14, 188, 25 }, new byte[] { 112, 114, 101, 100, 101, 102, 105, 110, 101, 100, 32, 107, 101, 121 } });

        migrationBuilder.UpdateData(
            table: "Users",
            keyColumn: "Id",
            keyValue: new Guid("c643b944-53d9-4a0c-9922-3486558b9129"),
            columns: new[] { "PasswordHash", "PasswordSalt" },
            values: new object[] { new byte[] { 211, 141, 232, 166, 77, 237, 128, 211, 121, 45, 47, 68, 211, 202, 162, 3, 39, 214, 212, 153, 4, 199, 223, 213, 43, 233, 224, 21, 107, 10, 62, 220, 105, 27, 254, 137, 16, 208, 56, 42, 254, 211, 154, 27, 60, 135, 197, 224, 148, 99, 232, 246, 220, 121, 113, 103, 42, 117, 172, 240, 134, 14, 188, 25 }, new byte[] { 112, 114, 101, 100, 101, 102, 105, 110, 101, 100, 32, 107, 101, 121 } });
    }

    protected override void Down(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.UpdateData(
            table: "Users",
            keyColumn: "Id",
            keyValue: new Guid("3b86f5a2-1978-46e3-a0b6-edbb6b558efc"),
            columns: new[] { "PasswordHash", "PasswordSalt" },
            values: new object[] { new byte[] { 211, 141, 232, 166, 77, 237, 128, 211, 121, 45, 47, 68, 211, 202, 162, 3, 39, 214, 212, 153, 4, 199, 223, 213, 43, 233, 224, 21, 107, 10, 62, 220, 105, 27, 254, 137, 16, 208, 56, 42, 254, 211, 154, 27, 60, 135, 197, 224, 148, 99, 232, 246, 220, 121, 113, 103, 42, 117, 172, 240, 134, 14, 188, 25 }, new byte[] { 112, 114, 101, 100, 101, 102, 105, 110, 101, 100, 32, 107, 101, 121 } });

        migrationBuilder.UpdateData(
            table: "Users",
            keyColumn: "Id",
            keyValue: new Guid("c643b944-53d9-4a0c-9922-3486558b9129"),
            columns: new[] { "PasswordHash", "PasswordSalt" },
            values: new object[] { new byte[] { 211, 141, 232, 166, 77, 237, 128, 211, 121, 45, 47, 68, 211, 202, 162, 3, 39, 214, 212, 153, 4, 199, 223, 213, 43, 233, 224, 21, 107, 10, 62, 220, 105, 27, 254, 137, 16, 208, 56, 42, 254, 211, 154, 27, 60, 135, 197, 224, 148, 99, 232, 246, 220, 121, 113, 103, 42, 117, 172, 240, 134, 14, 188, 25 }, new byte[] { 112, 114, 101, 100, 101, 102, 105, 110, 101, 100, 32, 107, 101, 121 } });
    }
}
}

Why it updates the Users without any change ? What am I missing ?

like image 651
gneric Avatar asked Mar 13 '19 22:03

gneric


1 Answers

You have to seed with the raw value to avoid this :

var users = new[]
        {
            new Users()
            {
                Id = new Guid("3b86f5a2-1978-46e3-a0b6-edbb6b558efc"),
                FirstName = "John",
                LastName = "Doe",
                DepositedCash = 10000,
                Email = "[email protected]",
                RoleId = roles[0].Id,
                PasswordHash = new byte[] { 211, 141, 232, 166, 77, 237, 128, 211, 121, 45, 47, 68, 211, 202, 162, 3, 39, 214, 212, 153, 4, 199, 223, 213, 43, 233, 224, 21, 107, 10, 62, 220, 105, 27, 254, 137, 16, 208, 56, 42, 254, 211, 154, 27, 60, 135, 197, 224, 148, 99, 232, 246, 220, 121, 113, 103, 42, 117, 172, 240, 134, 14, 188, 25 },
                PasswordSalt = new byte[] { 112, 114, 101, 100, 101, 102, 105, 110, 101, 100, 32, 107, 101, 121 }
            },
            new Users()
            {
                Id = new Guid("c643b944-53d9-4a0c-9922-3486558b9129"),
                FirstName = "Admin",
                LastName = "Admin",
                DepositedCash = 10000,
                Email = "[email protected]",
                RoleId = roles[1].Id,
                PasswordHash = new byte[] { 211, 141, 232, 166, 77, 237, 128, 211, 121, 45, 47, 68, 211, 202, 162, 3, 39, 214, 212, 153, 4, 199, 223, 213, 43, 233, 224, 21, 107, 10, 62, 220, 105, 27, 254, 137, 16, 208, 56, 42, 254, 211, 154, 27, 60, 135, 197, 224, 148, 99, 232, 246, 220, 121, 113, 103, 42, 117, 172, 240, 134, 14, 188, 25 },
                PasswordSalt = new byte[] { 112, 114, 101, 100, 101, 102, 105, 110, 101, 100, 32, 107, 101, 121 }
            }
        };

That way EF Core will generate a migration knowing this is a fixed value and will not update it in every migration. Using a method (HashPassword here) prevent EF Core from considering it as fixed.

like image 176
Adrien Desfarges Avatar answered Nov 13 '22 08:11

Adrien Desfarges