[英]Entity Framework Code First GenericTypeArguments
我有一個不幸的任務是創建一個同時使用MySQL和MSSQL數據庫的MVC項目。 為此,我首先使用Entity Framework 6代碼,並且在兩個數據庫上都可以使用它。
但是,問題在於MSSQL支持模式,而MYSQL不支持。 如果添加modelBuilder.Entity<Status>().ToTable("Status", schemaName: "Client");
我在構建MySQL數據庫時出錯。
為了解決這個問題,我嘗試將自定義屬性添加到所有DbSet中,以便能夠確定要使用的架構。 在MSSQL中,我將使用架構,而在MYSQL中,我將在表前添加架構名稱。
例如:
MSSQL:
Client.Status
Employee.Status
MYSQL:
Client_Status
Employee_Status
現在確定我要使用反射的類型和架構。 不幸的是,我無法在OnModelCreating
方法中使用GenericTypeArguments
。 它說'System.Type' does not contain a definition for 'GenericTypeArguments' and ...
但是,如果我將反射代碼復制到MVC控制器(單獨的項目)中的某個動作上,則它確實可以工作。
[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 });
}
}
您現在處於反思的境界。 嘗試如下所示的方法:
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 } );
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.