Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EFCoreStoreDbContext does not work with AddDbContext #777

Open
turkysha opened this issue Jan 16, 2024 · 3 comments
Open

EFCoreStoreDbContext does not work with AddDbContext #777

turkysha opened this issue Jan 16, 2024 · 3 comments
Labels

Comments

@turkysha
Copy link

So I am trying to use EF Core DbContext with Postgres. I want to have two separate contexts for handling Tenants and Application. Since I already have DI configured, I wanted to also DI MultitenantStoreDbContext. I also need to pass connection string so I can differ from Development and Production.

Migrations break because:
No database provider has been configured for this DbContext. A provider can be configured by overriding the 'DbContext.OnConfiguring' method or by using 'AddDbContext' on the application service provider. If 'AddDbContext' is used, then also ensure that your DbContext type accepts a DbContextOptions<TContext> object in its constructor and passes it to the base constructor for DbContext

DependencyInjection.cs

services.AddDbContext<IMultiTenantStoreDbContext, MultiTenantStoreDbContext>((options) =>
               options
                   .UseNpgsql(
                       connectionString,
                       b =>
                       {
                           b.EnableRetryOnFailure()
                            .MigrationsAssembly(typeof(MultiTenantStoreDbContext).Assembly.FullName);
                       }).EnableSensitiveDataLogging(), isContextTransient ? ServiceLifetime.Transient : ServiceLifetime.Scoped
               );

MultiTenantStoreDbContext.cs

public class MultiTenantStoreDbContext : EFCoreStoreDbContext<TenantInfo>, IMultiTenantStoreDbContext
    {
        public MultiTenantStoreDbContext(DbContextOptions<MultiTenantStoreDbContext> options) : base(options)
        {

        }

    }
@turkysha
Copy link
Author

I solved my problem by implementing my custom store but issue is still present

@AndrewTriesToCode
Copy link
Sponsor Contributor

Hi I’m glad you got a workaround. Just for a quick test can you make your db context inherit just DbContext and not the EFCoreStore context to see if the issue is general or specific to EFCoreStore?

@turkysha
Copy link
Author

turkysha commented Jan 17, 2024

Yeah, in my workaround, I have DbContext inherited.

MultiTenantStoreDbContext.cs

public class MultiTenantStoreDbContext : DbContext, IMultiTenantStore<TenantInfo>, IMultiTenantStoreDbContext
    {
        public MultiTenantStoreDbContext(DbContextOptions<MultiTenantStoreDbContext> options) : base(options)
        {

        }

        public virtual DbSet<TenantInfo> TenantInfos { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            modelBuilder.Entity<TenantInfo>().HasKey(ti => ti.Id);
            modelBuilder.Entity<TenantInfo>().Property(ti => ti.Id).HasMaxLength(64);
            modelBuilder.Entity<TenantInfo>().HasIndex(ti => ti.Identifier).IsUnique();
        }

        public async Task<IEnumerable<TenantInfo>> GetAllAsync()
        {
            return await TenantInfos.ToListAsync();
        }

        public async Task<bool> TryAddAsync(TenantInfo tenantInfo)
        {
            await TenantInfos.AddAsync(tenantInfo);
            try
            {
                await base.SaveChangesAsync();
                return true;
            } catch (Exception)
            {
                return false;
            }
        }

        public async Task<TenantInfo> TryGetAsync(string id)
        {
            return await TenantInfos.Where(e => e.Id == id).FirstOrDefaultAsync();
        }

        public async Task<TenantInfo> TryGetByIdentifierAsync(string identifier)
        {
            return await TenantInfos.Where(e => e.Identifier == identifier).FirstOrDefaultAsync();
        }

        public async Task<bool> TryRemoveAsync(string identifier)
        {
            TenantInfo tenantInfo = await TenantInfos.Where(e => e.Identifier == identifier).FirstOrDefaultAsync();

            if (tenantInfo == null)
            {
                return false;
            }

            TenantInfos.Remove(tenantInfo);
            try
            {
                await base.SaveChangesAsync();
                return true;
            } catch (Exception)
            {
                return false;
            }
        }

        public async Task<bool> TryUpdateAsync(TenantInfo tenantInfo)
        {
            TenantInfos.Update(tenantInfo);

            try
            {
                await base.SaveChangesAsync();
                return true;
            } catch(Exception)
            {
                return false;
            }
        }
    }

I think initial problem in store is that it is not passing Type with DbContextOptions, which is explicitly said it needs to be done by generated error. From what I seen, EFCoreStore have constructor with DbContextOptions, not with DbContextOptions<SomeType>.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

2 participants