简体   繁体   中英

Multi-tenancy in EF6 with multiple schemas having the same tables

In our system it has become required to provide a multi-tenant solution, where each tenant has the same data structure.

During investigation I came across an article discussing multi-tenancy with EF4.1.

http://romiller.com/2011/05/23/ef-4-1-multi-tenant-with-code-first/

This looks like a sensible solution, but we would prefer to avoid multiple database contexts if possible.

Also, we have a large number of migrations for our current single tenant solution. With EF6, it is possible for a migration to target a specific context and when none is supported, a default is targeted.

I have a couple of quesions here:

  1. Is there a better approach to multi-tenancy when using EF6 other than that specified for EF4?
  2. Is there a better way to handle the migrations?

Any help is much appreciated!

  1. Context is connecting to a connection string, if the connection string is resolved at runtime, then you are using One dbcontext class with httprequest specific instance. to distinguish httprequest, host name headers can be used.
  2. There is no easy way to handle migration. This is a complex question, but in short, before the end of release 1, i normally create a initial migration with all scripts to provision the database, this is to help the database created after this change it not effected by any migrations down the track. and then add migration every time i need to change it. let me know if more details needed.

I understand this is old, however it's still widely searched topic.

I have used the following methods successfully with having multi-tenant by schema, using Code-First or DB First using EDMX.

  1. DB First (EDMX) - Edit the three sections that make up your EDMX; SSDL, CSDL, and CS.
    • Remove any references to the Schema by replacing the schema name with nothing.
  2. Implement IDbCommandInterceptor and include command.CommandText = command.CommandText.Replace("<unwanted-schema-here>", "<your-actual-schema>") under all the *Executing implementations. Then Remove and Add the Interceptor before initializing a new context.

Example: Place your factory method inside a Partial class of your DbContext .

Private Shared _lschema As String
Public ReadOnly Property schema As String = _lschema

Public Shared Function GetContext(Optional connString As String = Nothing) As MyContext
   If connString IsNot Nothing Then
     Dim conn As EntityConnection = ContextHelper.CreateConnection(Of MyContext)(connString,ByRef _lschema) 
     DbInterception.Remove(New SchemaInterceptor)

     DbInterception.Add(New SchemaInterceptor(_lschema))
     Dim ctx = New MyContext(conn, False)
     ctx.Configuration.LazyLoadingEnabled = False
     ctx.Configuration.AutoDetectChangesEnabled = True

     Return ctx
   End If
   Return New MyContext()
End Function
  1. Work to build your own model dynamically, using IDbModelCacheKeyProvider , this is used in a similar method as the example above. Such as building your connection by calling a method that gets the schema of the connection and returning it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM