Base solution for your next web application
Open Closed

EF Core Seed Tenant Data #3591


User avatar
0
JeffMH created

We are struggling coming up with the right place to add code to seed tenant data. There are two scenarios when this needs to occur:

  1. When we create a new tenant
  2. On Database Migration.

We attempted to use the AbpZeroDbMigrator and pass in a seedAction to the CreateOrMigrateTenant function. The method that excepts this parameter is not part of IAbpZeroDbMigrator so we we couldn't call that within the TenantManager. We also tried overriding this method from within the AbpZeroDbMigrator in the EfCore project, and that didn't work because of a UnitOfWork / transaction locking issue.

Anyway, am I missing something easy here? We have default tenant data that has to be put in when we create and do migrations but I am am just not seeing a built in way to do this. I see the one for Hosts, but not tenants. Any help would be appreciated.

Using the latest version downloaded a couple weeks ago.


9 Answer(s)
  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    You are right, there is no built-in class for this. In EF Core, there is no seed also, because of that we run seed method in PostInitialize of EntityFrameworkCore module.

    You can modify SeedHelper class for your needs and it will be runned on app start. For new tenant creation, you can also use same class in CreateWithAdminUserAsync method of TenantManager just like we use

    await _demoDataBuilder.BuildForAsync(tenant);
    

    Thanks.

  • User Avatar
    0
    JeffMH created

    I think you guys jumped the gun on EF Core. This has been a nightmare moving our project to this. I think when you generate a project that targets the full framework, you should be given the option to use EF Core or just plain old EF. There are still things that just aren't ready in EF Core yet.

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @JeffMH,

    You are right, EF Core is missing some important features. But, it is also different from EF 6.x and it is hard to support two different templates with EF Core and EF 6.x for us.

    If you have any problems while developing tenant seed data, we will be very happy to help.

    Thanks.

  • User Avatar
    0
    exlnt created

    I am trying to do the exact same thing, I need to put some seed data into my tenant DB tables. Is there any way to achieve this in the .NET Core solution?

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @exlnt,

    You can modify SeedHelper to insert tenant data. You first need to get list of tenants and then execute same actions for each tenant.

    Or you can use migrator tool which does the exact same thing.

    Thanks.

  • User Avatar
    0
    pankajmathur created

    Hi, We are facing a big time problem with this issue. Can you please provide a sample code which can help use seed the data for the tenant while it is created using the SeedHelper.

  • User Avatar
    0
    rvanwoezik created

    I have an initial Companies Creator like this

    ublic class InitialCompaniesCreator
        {
            private readonly PhoogleDbContext _context;
    
            public InitialCompaniesCreator(PhoogleDbContext context)
            {
                _context = context;
            }
    
            public void Create()
            {
                var defaultTenant = _context.Tenants.IgnoreQueryFilters().FirstOrDefault(t => t.TenancyName == MultiTenancy.Tenant.DefaultTenantName);
                // Fysio Physics
                var fysioPhysics = _context.Companies.IgnoreQueryFilters().FirstOrDefault(c => c.CompanyName == "Fysio Physics");
                if (fysioPhysics == null)
                {
                    _context.Companies.Add(
                        new Company
                        {
                            CompanyName = "Fysio Physics",
                            TenantId = defaultTenant.Id
                        });
                    _context.SaveChanges();
                }
                // Basic-Fit
                var bf = _context.Companies.IgnoreQueryFilters().FirstOrDefault(c => c.CompanyName == "Basic-Fit");
                if (bf == null)
                {
                    _context.Companies.Add(
                        new Company
                        {
                            CompanyName = "Basic-Fit",
                            TenantId = defaultTenant.Id
                        });
                    _context.SaveChanges();
                }
    

    Which i call from the DefaultTenantBuilder.cs

    public void Create()
            {
                CreateDefaultTenant();
    
                new InitialCompaniesCreator(_context).Create();
               
                new InitialClinicCreator(_context).Create();
    
                new InitialCalendarEventCreator(_context).Create();
                
            }
    

    Hope this helps

  • User Avatar
    0
    ismcagdas created
    Support Team

    Thanks a lot @rvanwoezik :).

    @pankajmathur, is this what you are looking for or do you have another problem.

  • User Avatar
    0
    pankajmathur created

    Thanks!!! This is exactly that we were looking for however for now we have used the demobuilder