Coder Social home page Coder Social logo

multitenancy-aspnet-core's People

Contributors

iammukeshm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

multitenancy-aspnet-core's Issues

Can you help with the controller?

Hello, I am trying to set up a structure as in the picture below using the codes you shared.
enter image description here

The system administrator of this application is "Root User", a user with the ability to add other users to the system.

Gold, silver, bronze .. etc. will have an unlimited user base. Each will have their own database. Let's not get hung up on the naming. These will be in the form of individual customers, not as a group.

All users will log into the application from the same place. If the user is a system administrator, he will only see the area related to users. This is about frontend. If it is in normal user status, it will read the connection string from the "Shared DB" and connect to the relevant database.
I want to save Tenant definitions in "Shared DB" database. Appsettings.json will only have "Shared DB" information.

For example, when "Gold User" logs in, it will read its own connection string from "Shared DB" and continue its operations in "Gold DB". Also, it will not close the other connection so that it can read other data from "Shared DB".

I am trying to add "DB Context" in a multiple way. However, only the 2nd "DB Context" I added works in the controller. It crushes the first.
Can you help me with this part?

For now I'm pulling the Tenant definitions from the appsettings.json file. I am using .Net Core 6.0.

appsettings.json

{
  "Logging": {
	  "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "TenantSettings": {
    "Defaults": {
      "DBProvider": "mssql",
      "ConnectionString": "Server=192.168.0.78,1435;Database=tenant_SharedDB;User Id=sa;Password=***;"
    },
    "Tenants": [
      {
        "Name": "bronze",
        "TenantId": "bronze",
        "ConnectionString": "Server=192.168.0.78,1435;Database=tenant_BronzeTenantDB;User Id=sa;Password=***;"
      },
      {
        "Name": "silver",
        "TenantId": "silver",
        "ConnectionString": "Server=192.168.0.78,1435;Database=tenant_SilverTenantDB;User Id=sa;Password=***;"
      },
      {
        "Name": "gold",
        "TenantId": "gold",
        "ConnectionString": "Server=192.168.0.78,1435;Database=tenant_GoldTenantDB;User Id=sa;Password=***;"
      }
    ]
  }
}

Program.cs

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddHttpContextAccessor();
builder.Services.Configure<TenantSettings>(builder.Configuration.GetSection("TenantSettings"));
builder.Services.AddInfrastructureService();

await builder.Services.AddPersistenceService();

builder.Services.AddSwaggerGen();
var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI(c =>
    {
        c.SwaggerEndpoint("/swagger/UserControllers/swagger.json", "MultiTenantWebApi - User Tables");
        c.SwaggerEndpoint("/swagger/ProductControllers/swagger.json", "MultiTenantWebApi - Product Tables");
    });
}

//app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

ServiceRegistration.cs

public static class ServiceRegistration
{
    public static void AddInfrastructureService(this IServiceCollection collection)
    {
        collection.AddTransient<ITenantService, TenantService>();
    }

    public static async Task AddPersistenceService(this IServiceCollection collection)
    {
        collection.AddScoped<IUserService, UserService>();
        collection.AddScoped<IProductService, ProductService>();

        using var provider = collection.BuildServiceProvider();
        var configuration = provider.GetRequiredService<IConfiguration>();
        var tenantSettings = configuration.GetSection("TenantSettings").Get<TenantSettings>();

        var defaultConnectionString = tenantSettings.Defaults?.ConnectionString;
        var defaultDbProvider = tenantSettings.Defaults?.DbProvider;
        
        if (defaultDbProvider.ToLower() == "mssql")
        {
            collection.AddDbContext<SharedDbContext>(option => option.UseSqlServer(e => e.MigrationsAssembly(typeof(SharedDbContext).Assembly.FullName)));
        }

        using IServiceScope scope = collection.BuildServiceProvider().CreateScope();
        // SharedDb Migration
        var dbContext = scope.ServiceProvider.GetRequiredService<SharedDbContext>();
        dbContext.Database.SetConnectionString(defaultConnectionString);
        if (dbContext.Database.GetMigrations().Count() > 0)
            await dbContext.Database.MigrateAsync();

        if (defaultDbProvider.ToLower() == "mssql")
        {
            collection.AddDbContext<TenantDbContext>(option => option.UseSqlServer(e => e.MigrationsAssembly(typeof(TenantDbContext).Assembly.FullName)));
        }

        using IServiceScope scope2 = collection.BuildServiceProvider().CreateScope();
        foreach (var tenant in tenantSettings.Tenants)
        {
            string connectionString = tenant.ConnectionString switch
            {
                null => defaultConnectionString,
                not null => tenant.ConnectionString
            };
            var dbContext2 = scope2.ServiceProvider.GetRequiredService<TenantDbContext>();
            dbContext2.Database.SetConnectionString(connectionString);
            if (dbContext2.Database.GetMigrations().Count() > 0)
                await dbContext2.Database.MigrateAsync();
        }
    }
}

With these codes, migrations are working correctly. I have bound the User table to the SharedDbContext. I also bound the Product table to TenantDbContext. The tables are created in the corresponding databases.

Product listing and adding products work correctly in the controller. But user listing, adding user is not working. I am getting an error like this:
enter image description here

I just need help with controller. Because I couldn't find enough resources for .net core. I don't have enough knowledge. What do I need to do for the controller to work properly?

I wish you good work.

Error when removing migration ("relational store [..] without either DbConnection or connection string")

Hi,

Thanks for this project! Unfortunately I'm having difficulties when trying to remove a migration. Running the project and adding migrations works without problems, executing "remove-migration" results in the following error message:

PM> Remove-Migration
Build started...
Build succeeded.
System.InvalidOperationException: A relational store has been configured without specifying either the DbConnection or connection string to use.
   at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.get_DbConnection()
   at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.Open(Boolean errorsExpected)
   at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerDatabaseCreator.<>c__DisplayClass18_0.<Exists>b__0(DateTime giveUp)
   at Microsoft.EntityFrameworkCore.ExecutionStrategyExtensions.<>c__DisplayClass12_0`2.<Execute>b__0(DbContext c, TState s)
   at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
   at Microsoft.EntityFrameworkCore.ExecutionStrategyExtensions.Execute[TState,TResult](IExecutionStrategy strategy, TState state, Func`2 operation, Func`2 verifySucceeded)
   at Microsoft.EntityFrameworkCore.ExecutionStrategyExtensions.Execute[TState,TResult](IExecutionStrategy strategy, TState state, Func`2 operation)
   at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerDatabaseCreator.Exists(Boolean retryOnNotExists)
   at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerDatabaseCreator.Exists()
   at Microsoft.EntityFrameworkCore.Migrations.HistoryRepository.Exists()
   at Microsoft.EntityFrameworkCore.Migrations.HistoryRepository.GetAppliedMigrations()
   at Microsoft.EntityFrameworkCore.Migrations.Design.MigrationsScaffolder.RemoveMigration(String projectDir, String rootNamespace, Boolean force, String language)
   at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.RemoveMigration(String contextType, Boolean force)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.RemoveMigrationImpl(String contextType, Boolean force)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.RemoveMigration.<>c__DisplayClass0_0.<.ctor>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_0`1.<Execute>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
**A relational store has been configured without specifying either the DbConnection or connection string to use.**

Steps to reproduce:

  1. Clone repo
  2. Execute project, post some new records to the "Products"-endpoint
  3. Add simple property to Product entity (like 'public string Something { get; set; }')
  4. add-migration "test"
  5. run
  6. remove-migration => error message

Do you know how to solve this issue?

Please upgrade to .NET 6 (current .NET 5)

Please upgrade to .NET 6 (current .NET 5)

It was not possible to find any compatible framework version
The framework 'Microsoft.AspNetCore.App', version '5.0.0' (x64) was not found.
  - The following frameworks were found:
      6.0.3 at [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
      7.0.0-preview.3.22178.4 at [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]

You can resolve the problem by installing the specified framework and/or SDK.

The specified framework can be found at:
  - https://aka.ms/dotnet-core-applaunch?framework=Microsoft.AspNetCore.App&framework_version=5.0.0&arch=x64&rid=win10-x64

D:\github\multitenancy-aspnet-core\Multitenant.Api\bin\Debug\net5.0\Multitenant.Api.exe (process 12484) exited with code -2147450730.
To automatically close the console when debugging stops, enable Tools->Options->Debugging->Automatically close the console when debugging stops.
Press any key to close this window . . .

image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.