Entity Framework Core Migrations Custom History Table Column

ef-migrations entity-framework-core

Question

I'm trying to figure out how to add and set the value of a custom column in the Migrations history table. I've figured out how to add the column with a custom SqlServerHistoryRepository like this:

class MyHistoryRepository : SqlServerHistoryRepository
{
    public MyHistoryRepository(HistoryRepositoryDependencies dependencies) : base(dependencies)
    {            
    }

    protected override void ConfigureTable(EntityTypeBuilder<HistoryRow> history)
    {
        base.ConfigureTable(history);
        history.Property<DateTime>("Applied").HasDefaultValue(DateTime.Now);
        history.Property<string>("UserStamp");
    }
}`

I'm creating my data layer in a library that targets .NET Standard. I've created an IDesignTimeDbContextFactory for the migrations that looks like this.

public class MyDbContextFactory : IDesignTimeDbContextFactory<MyContext>
{
    public MyContext CreateDbContext(string[] args)
    {
        var optionsBuilder = new DbContextOptionsBuilder<MyContext>();
        optionsBuilder.UseSqlServer("connectionString",
            ob => ob.MigrationsAssembly(this.GetType().Assembly.GetName().Name))
            .ReplaceService<IHistoryRepository, MyHistoryRepository>();

        return new MyContext(optionsBuilder.Options);
    }
}

How can I pass a value for UserStamp into the migrations history table?

1
0
8/22/2018 4:57:27 PM

Accepted Answer

You can use dependency injection to pass any service directly into your implementation of IHistoryRepository.

For instance, to read a value from a file you can do the following:

public class MyHistoryRepository : NpgsqlHistoryRepository
{
    private readonly IConfiguration _config;

    public MyHistoryRepository(
        HistoryRepositoryDependencies dependencies,
        IConfiguration config) : base(dependencies)
    {
        _config = config;
    }

    protected override void ConfigureTable(EntityTypeBuilder<HistoryRow> history)
    {
        base.ConfigureTable(history);
        history.Property<DateTime>("Applied").HasDefaultValue(DateTime.Now);
        history.Property<string>("UserStamp")
            .HasDefaultValue(_config["UserStamp"] ?? "");
    }
}

public class MyDbContextFactory : IDesignTimeDbContextFactory<MyContext>
{
    public MyContext CreateDbContext(string[] args)
    {
        var services = new ServiceCollection();

        IConfiguration config = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("config.json")
            .Build();

        // in your case this would probably be 'AddEntityFrameworkSqlServer'
        services.AddEntityFrameworkNpgsql();
        services.AddSingleton<IConfiguration>(config);
        services.AddScoped<IHistoryRepository, MyHistoryRepository>();

        var optionsBuilder = new DbContextOptionsBuilder<MyContext>();
        optionsBuilder.UseNpgsql(config.GetConnectionString("DefaultConnection"))
            .UseInternalServiceProvider(services.BuildServiceProvider());

        return new MyContext(optionsBuilder.Options);
    }
}
0
8/26/2018 6:43:32 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow