{"id":20253166,"url":"https://github.com/jeremylikness/blazorefcoremultitenant","last_synced_at":"2025-04-10T23:32:55.624Z","repository":{"id":77125914,"uuid":"361868336","full_name":"JeremyLikness/BlazorEFCoreMultitenant","owner":"JeremyLikness","description":"Examples of multitenancy using EF Core and Blazor.","archived":false,"fork":false,"pushed_at":"2021-04-29T23:35:56.000Z","size":227,"stargazers_count":81,"open_issues_count":2,"forks_count":18,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-03-24T20:21:46.067Z","etag":null,"topics":["blazor","efcore","entity-framework","entity-framework-core","multiple-database","single-database","tenant"],"latest_commit_sha":null,"homepage":"https://blog.jeremylikness.com/blog/multitenancy-with-ef-core-in-blazor-server-apps/","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JeremyLikness.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-04-26T19:22:20.000Z","updated_at":"2025-02-25T08:26:18.000Z","dependencies_parsed_at":null,"dependency_job_id":"db7d50a8-7e6c-4b31-b967-aaaef34d559c","html_url":"https://github.com/JeremyLikness/BlazorEFCoreMultitenant","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JeremyLikness%2FBlazorEFCoreMultitenant","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JeremyLikness%2FBlazorEFCoreMultitenant/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JeremyLikness%2FBlazorEFCoreMultitenant/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JeremyLikness%2FBlazorEFCoreMultitenant/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JeremyLikness","download_url":"https://codeload.github.com/JeremyLikness/BlazorEFCoreMultitenant/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248316881,"owners_count":21083515,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["blazor","efcore","entity-framework","entity-framework-core","multiple-database","single-database","tenant"],"created_at":"2024-11-14T10:21:49.215Z","updated_at":"2025-04-10T23:32:55.616Z","avatar_url":"https://github.com/JeremyLikness.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Blazor EF Core Multitenant\n\nExamples of using multi-tenancy with Entity Framework Core in a Blazor app using the data context factory.\n\nRead the related, detailed blog post [here](https://blog.jeremylikness.com/blog/multitenancy-with-ef-core-in-blazor-server-apps/).\n\n## Quickstart\n\n1. Clone the repository: `git clone https://github.com/JeremyLikness/BlazorEFCoreMultitenant`\n1. Launch the app\n    1. Open in VS Code and hit F5, or\n    1. Open in Visual Studio and hit F5, or\n    1. From a command line at the root of the project, type `dotnet run`\n1. The databases ship with the project. If you need to create them or wish to recreate them, delete the `.sqlite` files then use the button on the main page of the app to regenerate them.\n1. Select your tenant and navigate to the multidatabase or single database solutions.\n\nThe database simply tracks methods and parameters. The `ParentType` is used for the \"tenant.\"\n\n## Notes\n\nThis example shows two different solutions. Both configure the context in a way that makes the tenancy ambient to the consumer. The code simply loads the list of `DataMethod` \ninstances without filters, but only the tenant-specific items are returned. This is because the single database approach uses a global query filter and the multiple database\napproach uses a differnet database altogether for each tenant.\n\n### Single Database\n\nFor a single database, the column to hold tenant in this example is `ParentType`. It could be a `tenantId` or some other field. The factory is set to `Scoped` instead of singleton so \nit can acquire the instance of `TenantProvider` that is running for the current user. This will cache the options, which is fine for a single database. It also caches the instance of \nof the `TenantProvider`. This is the same one use in the rest of the application, so the `OnModelBuilding` override is able to add a global filter based on the current tenant.\n\n### Multiple Databases\n\nFor multiple databases, the database is named after the tenant so there is a one-to-one mapping. Instead of using a global filter, the tenant is used to build the connection string\nand passed back. To allow the case when a user might change their tenant \"on the fly\" the factory is scoped as `Transient` instead so the tenant is always re-evaluated in case it\nchanges.\n\n## Performance\n\nYou can use the benchmark project to evaluate performance. Be sure to run it in `Release` mode:\n\n```bash\ndotnet run -c Release\n```\n\nHere are the results on my laptop:\n\n|          Method |     Mean |     Error |    StdDev |\n|---------------- |---------:|----------:|----------:|\n|   SingleContext | 1.134 us | 0.0224 us | 0.0249 us |\n| MultipleContext | 3.087 us | 0.0608 us | 0.0964 us |\n\nAlthough the `Transient` is slower than `Scoped`, it is still a fast operation.\nAnother way to think about 3us is 333k requests per second.\n\n---\n\nFeedback? Questions? Message me on Twitter: [@JeremyLikness](https:///www.twitter.com/jeremylikness)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjeremylikness%2Fblazorefcoremultitenant","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjeremylikness%2Fblazorefcoremultitenant","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjeremylikness%2Fblazorefcoremultitenant/lists"}