The task is the following: when registering a client, it is necessary to create a set of tables with a unique prefix in the database, is it possible to implement this using EF?

  • What does it mean with unique? Is each table different or all shared but one application specific? - Dmitry
  • And where does ASP.net? - VladD
  • If you are given an exhaustive answer, mark it as correct (a daw opposite the selected answer). - Nicolas Chabanovsky

2 answers 2

Add to the context of working with the base for each model:

modelBuilder.Entity<YourModel>().ToTable(prefix+"tableName", "dbo"); 

    Yes it is possible.

    You will need to describe the structure of your tables in the form of entities - as I understand it, it will be identical for different users?

    Then, using the fluent API, it will be necessary to bind entities and tables — in fact, indicate that this class will be mapped onto a table with such a name.

    Concrete

    Suppose you want to create for each user a single table of this type:

     public UserValue { public int Id { get; set; } public string Value { get; set; } } 

    We need a descendant of DbContext which describes the necessary tables with a given prefix:

     public MyDbContext : DbContext { public virtual DbSet<UserValue> UserValues { get; set; } public MyDbContext(string prefix) : base(PrepareCompiledModel(prefix)) { } private static DbCompiledModel PrepareCompiledModel(string prefix) { var builder = new DbModelBuilder(); builder.Entity<UserValue>.ToTable(prefix + "UserValue"); return builder.Compile(); } } 

    Please note that building a model is a resource-intensive task. EF itself is able to cache built and compiled models, but in your case of a very dynamic database model you will have to attend to this yourself.

    In the simple case, you can create a static dictionary ( static IDictionary<string, DbCompiledModel> ) inside the MyDbContext class and check in the PrepareCompiledModel method PrepareCompiledModel there are already models with such a prefix.

    Using

    You will have the main (static) database context in which the table names are fixed. From there you will read the prefix for each specific user.

     var staticContext = new StaticDbContext(); var prefix = staticContext.Users.Single(u => u.Id == id).Prefix; var dynamicContext = new MyDbContext(prefix); var foos = dynamicContext.UserValues.Where(uv => uv.Value == "foo");