Search code examples
entity-framework-coreasp.net-core-2.1

IHostingEnvironment how to pass OnModelCreating?


I want to create some dummy data that I will load from a json file. I need to get the path to the file, from my research I found that I need IHostingEnvironment but I am not sure how to get the property in my DbContext class file.


Solution

  • If you were to use an external "Initializer" class instead (in the context of an ASP.NET Core app at least) you might make something like this:

    DbContext class:

    public class SampleDbContext : Microsoft.EntityFrameworkCore.DbContext {
        public SampleDbContext(DbContextOptions<SampleDbContext> options) : base(options) { }
    
        public DbSet<SampleRecord> SampleRecords { get; set; }
    
        //...Other DB structure here
    
        protected override void OnModelCreating(ModelBuilder modelBuilder) {
            //...
        }
    }
    

    Initializer class:

    public static void Initialize(SampleDbContext context, var JSONStringOrObj) {
        context.Database.EnsureCreated();
    
        //Data seeding sample
        if(!context.SampleRecords.Any()) {
            context.SampleTable.AddRange(new SampleTable[]
            {
                new SampleRecord() { SampleData = "Test1" },
                new SampleRecord() { SampleData = "Test2" },
                new SampleRecord() { SampleData = "Test3" },
                new SampleRecord() { SampleData = "Test4" }
            });
        }
    
        //Extract seed data from JSON and add to proper DbSet ...
    
        context.SaveChanges();
    }
    

    Startup.cs:

    public class Startup {
    
        public IHostingEnvironment HostingEnvironment { get; }
    
        public Startup(IHostingEnvironment env) {
            //...
    
            HostingEnvironment = env;
    
            //...
        }
    
        public void ConfigureServices(IServiceCollection services) {
            //...
    
            services.AddDbContext<SampleDbContext>(/*Your options here*/);
    
            services.AddSingleton<IHostingEnvironment>(HostingEnvironment);
    
            //...
        }
    
        //... Rest of class
    }
    

    Program.cs:

    public class Program {
        public static void Main(string[] args) {
            var host = CreateWebHostBuilder(args).Build()
    
            using (var scope = host.Services.CreateScope()) {
                var services = scope.ServiceProvider;
                var hostingEnvironment = services.GetService<IHostingEnvironment>();
    
                //... do whatever you need to get your JSON file here (var jsonData = ...)
    
                var sampleDbContext = services.GetService<SampleDbContext>();
                Initializer.Initialize(sampleDbContext, jsonData);
            }
    
            host.Run();
        }
    
        //... Rest of class
    }
    

    The seed data will stay separate from your schema and will be loaded into the database when your app runs. You can also call the initializer from testing code (or not if you want to put specific test data in for tests).