我有一个不幸的任务是创建一个同时使用MySQL和MSSQL数据库的MVC项目。为此,我首先使用Entity Framework 6代码并在两个数据库上工作。
然而问题是MSSQL支持Schema而MYSQL不支持。如果我添加modelBuilder.Entity<Status>().ToTable("Status", schemaName: "Client");
,我会在构建MySQL数据库时出错。
为了解决这个问题,我尝试将自定义属性添加到我的所有DbSet中,以便能够确定我想要使用的模式。在MSSQL中,我将使用模式,在MYSQL中,我将在表格前加上模式名称。
EG:
MSSQL:
Client.Status
Employee.Status
MYSQL:
Client_Status
Employee_Status
现在确定我想要使用反射的类型和模式。很遗憾,我无法在GenericTypeArguments
方法中使用OnModelCreating
。它说'System.Type' does not contain a definition for 'GenericTypeArguments' and ...
但是,如果我将反射代码复制到我的MVC Controller(单独项目)中的一个动作,它确实有效。
[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);
}
}
如果我使用var type =
取消注释该行并启用调试,我也可以在检查器中看到GenericTypeArguments
。
那么如何使用GenericTypeArguments或类似的东西动态获取Tables.Status
类型或动态更改模式和表名的替代方法。
更新:
我设法通过首先将其转换为动态来获取类型。但是,Moho引入的代码的第二部分失败了
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 });
}
}
答案 0 :(得分:1)
你现在正处于反思的范畴。尝试类似下面的内容:
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 } );