1

how can i Add DbSet to my dbContext class, programmatically. [

        public class MyDBContext : DbContext 
        {
          
            public MyDBContext() : base("MyCon")
            {
               

                Database.SetInitializer<MyDBContext>(new CreateDatabaseIfNotExists<MyDBContext>());

            }
       
//Do this part programatically:
            public DbSet<Admin> Admins { get; set; }        
            public DbSet<MyXosh> MyProperty { get; set; }

        }

][1]

i want to add my model classes by ((C# Code-DOM)) and of course i did. but now i have problem with creating DbSet properties inside my Context class ...

Iman Salehi
  • 908
  • 2
  • 14
  • 34
  • You can't. The DbSet's are properties of the DbContext, and you can't expand existing objects at runtime. However, you can get the DbSet's of any mapped types using the context.Set() property. – DevilSuichiro Oct 01 '16 at 08:58
  • so how can i create table dynamically if i cant create dbset inside db context ?...have you any solution for this? – Iman Salehi Oct 01 '16 at 09:17
  • you can go without DbSet's entirely, override your OnModelCreating and map only those types you are actually going to use. – DevilSuichiro Oct 01 '16 at 14:37
  • @DevilSuichiro Yes you are right ..I did it – Iman Salehi Oct 02 '16 at 05:48

2 Answers2

2

yes i did!.. this: https://romiller.com/2012/03/26/dynamically-building-a-model-with-code-first/

And this: Create Table, Run Time using entity framework Code-First

are solution. no need to dispute with dbSets directly. it just works by do some thing like that:

  public class MyDBContext : DbContext
{

    public MyDBContext() : base("MyCon")
    {
        Database.SetInitializer<MyDBContext>(new CreateDatabaseIfNotExists<MyDBContext>());
    }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        var entityMethod = typeof(DbModelBuilder).GetMethod("Entity");
        var theList = Assembly.GetExecutingAssembly().GetTypes()
                  .Where(t => t.Namespace == "FullDynamicWepApp.Data.Domins")
                  .ToList();
        foreach (var item in theList)
        {
            entityMethod.MakeGenericMethod(item)
                           .Invoke(modelBuilder, new object[] { });
        }
        base.OnModelCreating(modelBuilder);
    }

}
Community
  • 1
  • 1
Iman Salehi
  • 908
  • 2
  • 14
  • 34
  • Nice solution but why didn't you just create also MyDBContext with codedom? – bubi Oct 02 '16 at 08:33
  • 1
    this solution is better, it doesn't need amount of code and generate a new dbcontext class for each model creating. @bubi – Iman Salehi Oct 03 '16 at 05:12
1

For those using EF Core that stubble here:

The code below is only for one table with the generic type. If you want more types you can always pass them through the constructor and run a cycle.

public class TableContextGeneric<T> : DbContext where T : class
{
    private readonly string _connectionString;

    //public virtual DbSet<T> table { get; set; }

    public TableContextGeneric(string connectionString)
    {
        _connectionString = connectionString;
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        var entityMethod = typeof(ModelBuilder).GetMethods().First(e => e.Name == "Entity");

        //the cycle will be run here
        entityMethod?.MakeGenericMethod(typeof(T))
            .Invoke(modelBuilder, new object[] { });

        base.OnModelCreating(modelBuilder);
    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer(_connectionString); // can be anyone 
    }
}
Júlio Almeida
  • 1,539
  • 15
  • 23
  • 1
    Could you provide an usage example please? – gsubiran Jul 17 '20 at 20:37
  • create a database based on certain types. Pratical example: Automatic invoice database creation based on the fields that you pass them. Using the code above, you just need to have this types and you can create a database. – Júlio Almeida Jul 18 '20 at 14:08