I have the unfortunate task to create an MVC project that uses both an MySQL and MSSQL database. To do that I use Entity Framework 6 code first and its working on both databases.
The problem however is that MSSQL supports Schemas and MYSQL does not. If I add the modelBuilder.Entity<Status>().ToTable("Status", schemaName: "Client");
I get an error building the MySQL database.
To solve this I tried adding a custom attribute to all my DbSets to be able to determine the schema I want to use. In MSSQL I will use the schema and in MYSQL I will prefix the table with the schema name.
EG:
MSSQL:
Client.Status
Employee.Status
MYSQL:
Client_Status
Employee_Status
Now to determine the types and schemas I want to use reflection. Unfortunately I cannot use the GenericTypeArguments
in the OnModelCreating
method. It says 'System.Type' does not contain a definition for 'GenericTypeArguments' and ...
However, if I copy the reflection code to an action in my MVC Controller (seperate project), it does work.
[TableSchema("Status", "Client")]
public DbSet<Tables.Status> Status { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//launch debugger to see inspector
if (System.Diagnostics.Debugger.IsAttached == false)
System.Diagnostics.Debugger.Launch();
//use schema or not
var useSchema = ConfigurationManager.AppSettings["UseSchema"] == "true";
//get all properties
PropertyInfo[] properties = typeof(DataContext).GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (PropertyInfo p in properties)
{
// Only work with dbsets
if (p.PropertyType.Name != "DbSet`1") { continue; }
//get tableschema attribute
var attribute = p.GetCustomAttributes(typeof(TableSchema), false).First();
//the line below reports the error on building
var type = p.PropertyType.GenericTypeArguments.First().Name;
//the goal is to use something like
modelBuilder.Entity<type>().ToTable(attribute.Table, attribute.Schema);
}
}
If I uncomment the line with var type =
and enable debugging, I am also able to see the GenericTypeArguments
in the inspector.
So how can I use the GenericTypeArguments or something similar to dynamically get the Tables.Status
type or an alternative to alter schemas and tablenames dynamically.
UPDATE:
I managed to get the type by casting it to a dynamic first. But then the second part of the code as introduced by Moho fails
var type = ((dynamic)p).PropertyType.GenericTypeArguments[0];
if (type != null)
{
var t = modelBuilder.GetType();
var m = t.GetMethod("Entity", BindingFlags.Public);
//System.NullReferenceException
var mgm = m.MakeGenericMethod((Type)type);
var entityTypeConfig = mgm.Invoke(modelBuilder, new object[] { });
if (!useSchema)
{
entityTypeConfig.GetType()
.GetMethods()
.Single(mi => mi.Name == "ToTable" && mi.GetParameters().Count()==1)
.Invoke(entityTypeConfig, new object[] { attribute.Schema + "_" + attribute.Table });
}
else
{
entityTypeConfig.GetType()
.GetMethods()
.Single(mi => mi.Name == "ToTable" && mi.GetParameters().Count() == 2)
.Invoke(entityTypeConfig, new object[] { attribute.Table, attribute.Schema });
}
}
You're in the realm of reflection now. Try something like the below:
var entityTypeConfig = modelBuilder.GetType()
.GetMethod( "Entity" )
.MakeGenericMethod( type )
.Invoke( modelBuilder, new object[] { } );
entityTypeConfig.GetType()
.GetMethods()
.Single( mi => mi.Name == "ToTable" && mi.GetParameters().Count == 2 )
.Invoke( entityTypeConfig, new object[] { attribute.Table, attribute.Schema } );
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.