2014-10-18 37 views
3

獲取dbset名稱目的: 我需要獲取實體的dbset名稱 typeof(UserAccount)=「UserAccounts」。 但是在運行時我需要一個通用類型的循環,因此不知道示例「UserAccount」。 只有來自typeof的「名稱」?EF在運行時從類型

我用一些實體創建了一個DbContext。 我一直在谷歌搜索了一段時間,但它似乎並沒有爲我工作,因爲類型轉換?

請參閱我的方法GetDbSetName在本說明的底部。

我在這個EF東西很新的 - 所以幫助我的問題,請配有下面;-)

public class MyEntities : DbContext 
{ 
    public DbSet<UserAccount> UserAccounts { get; set;} 
    public DbSet<UserRole> UserRoles { get; set; } 
    public DbSet<UserAccountRole> UserAccountRoles { get; set; } 
} 

描述定義類型的列表來控制輸出:

public static List<Type> ModelListSorted() 
{ 
    List<Type> modelListSorted = new List<Type>(); 
    modelListSorted.Add(typeof(UserRole)); 
    modelListSorted.Add(typeof(UserAccountRole)); 
    modelListSorted.Add(typeof(UserAccount)); 
    return modelListSorted; 
} 

問題在於使用類型 - 如果我使用「UserAccount」它工作,我得到「UserAccounts」。 但我在運行時沒有「UserAccount」,因爲我處於一系列類型的循環中。 我只有類型列表給予電子

public static loopList() 
{ 
    List<Type> modelListSorted = ModelListSorted(); 
    foreach (Type currentType in modelListSorted) 
    { 
     string s = DataHelper.GetDbSetName(currentType, db); 
    } 
} 

這裏是方法給我CHALLANGES ;-) 含義不進行編譯。 說我缺少一個程序集? 我知道這很僞,但這可以順利完成嗎?

public static string GetDbSetName(Type parmType, MyEntities db) 
{ 
    string dbsetname = (db as IObjectContextAdapter).ObjectContext.CreateObjectSet<parmType>().EntitySet.Name; 
    return dbsetname; 
} 

回答

2

的這裏的挑戰是,兩個反射步驟都參與其中,一個調用通用CreateObjectSet方法之一,得到的結果的EntitySet。這裏有一個辦法做到這一點:

首先,該方法:

string GetObjectSetName(ObjectContext oc, MethodInfo createObjectSetMethodInfo, 
         Type objectSetType, Type entityType) 
{ 
    var objectSet = createObjectSetMethodInfo.MakeGenericMethod(entityType) 
              .Invoke(oc, null); 
    var pi = objectSetType.MakeGenericType(entityType).GetProperty("EntitySet"); 
    var entitySet = pi.GetValue(objectSet) as EntitySet; 
    return entitySet.Name; 
} 

正如你看到的,我首先調用MethodInfo代表泛型方法CreateObjectSet<T>()得到ObjectSet。然後我找到PropertyInfoEntitySet屬性的通用類型ObectSet<T>。最後,我得到這個屬性的值和獲得的EntitySet的名稱。

要做到這一點,我第一次得到MethodInfoCreateObjectSet<>()(一個無參數)和ObjectSet<>

var createObjectSetMethodInfo = 
    typeof(ObjectContext).GetMethods() 
         .Single(i => i.Name == "CreateObjectSet" 
            && !i.GetParameters().Any()); 

var objectSetType = Assembly.GetAssembly(typeof(ObjectContext)) 
          .GetTypes() 
          .Single(t => t.Name == "ObjectSet`1"); 

GetObjectSetName他們的共通參數由一個具體的實體類型,這是由這些做規定「MakeGeneric ...」方法。

var oc = (dbContextInstance as IObjectContextAdapter).ObjectContext; 
var entityType = typeof(UserRole); 
var name = GetObjectSetName(oc, createObjectSetMethodInfo, objectSetType, entityType); 

在EF 6這些應該是using S:

using System.Data.Entity.Core.Metadata.Edm 
using System.Data.Entity.Core.Objects 
using System.Data.Entity.Infrastructure 
using System.Linq 
using System.Reflection 
+0

嗨@GertArnold。感謝您的回覆 - 好的和簡單的思考! 我得到錯誤在行:'var objectSet = createObjectSetMethodInfo.MakeGenericMethod(entityType).Invoke(oc,null);' 異常消息:{「對象不符合目標類型。」} – pladekusken 2014-10-19 16:09:04

+0

我認爲問題是在這裏:var oc =(dbContextInstance as IObjectContextAdapter).ObjectContext;' 正如我們所期望的System.Data.Objects.ObjectContext,但獲取System.Data.Entity.Core.ObjectContext? - 但我不知道如何解決它? – pladekusken 2014-10-19 16:09:30

+0

此行'var entitySet = pi.GetValue(objectSet)爲EntitySet;' 異常消息:{「對象與目標類型不匹配。」} 您是否也可以幫助解決此問題? – pladekusken 2014-10-19 16:50:28