When using EntityFramework with the Code First approach, you usually derive from DbContext and create DbSet properties for all entity types you have.
I can't do this because my software can be used with modules that provide new entity types that are not known at compile time.
So I would like to determine the list of available entity types at runtime.
I got it partially working with this code:
public class MyDbContext: DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
var entityMethod = typeof(DbModelBuilder).GetMethod("Entity");
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
// Register all types that derive from ModelBase as entity types
var entityTypes = assembly
.GetTypes()
.Where(t => t.IsSubclassOf(typeof(ModelBase)));
foreach (var type in entityTypes)
{
entityMethod.MakeGenericMethod(type)
.Invoke(modelBuilder, new object[] { });
}
}
}
}
However, when I do this, OnModelCreating
is never called. I have to add a DbSet to my class. I can not even make the DbSet private or internal, it has to be public, which makes it an ugly workaround:
public DbSet<DummyType> DummyTypes { get; set; }
public MyDbContext(string connectionName):
base(connectionName)
{
// Force initialization to make sure OnModelCreating
// has been called after leaving the constructor
DummyTypes.Count();
}
When adding this workaround, I can access the DbSets by calling the DbContext.Set<EntityType>()
method, so everything works as intended.
Question: Is there a way to achieve the same thing without adding a public DbSet property to my class?
DbContext.Set<EntityType>()
? configuring using code can be complex, your reflection code is just simple, what about the mappings? isn't that mappings is also dynamic? Your model seems empty at compile time. So I think you can try creating your DbContext using constructor accepting aDbCompiledModel
. DbCompiledModel can be obtained fromCompile
method ofDbModel
which can be obtained fromBuild
method ofDbModelBuilder
. That means you start from aDbModelBuilder
as an instance created any where you like. - Hopeless