EF在运行时从Type获取dbset名称

时间:2014-10-18 13:53:03

标签: entity-framework type-conversion dbcontext typeof dbset

目的: 我需要获取实体的dbset名称 typeof(UserAccount)=" UserAccounts"。 但是在运行时我需要循环的通用类型,因此不知道示例" UserAccount"。 只有"名称"来自typeof?

我用一些实体创建了一个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; }
}

定义一个Type列表来控制输出:

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;
}

问题在于使用类型 - 如果我使用&#34; UserAccount&#34;它工作,我得到&#34; UserAccounts&#34;。 但我没有&#34; UserAccount&#34;在运行时,因为我在一个类型的系列循环中。 我只有类型列表给出了e

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

这是给我挑战的方法; - ) 意思是不编译。 说我错过了集会? 我知道它很伪,但可以顺利完成吗?

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

1 个答案:

答案 0 :(得分: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;
}

如您所见,我首先通过调用代表通用方法ObjectSet的{​​{1}}来获取MethodInfo。然后,我找到了泛型CreateObjectSet<T>()的{​​{1}}属性的PropertyInfo。最后,我获得了此属性的值以及获得的EntitySet的名称。

要执行此操作,我首先获得ObectSet<T> EntitySet(没有参数的那个)和MethodInfo类型

CreateObjectSet<>()

ObjectSet<>中,它们的通用参数由具体的实体类型指定,这由这些&#34; MakeGeneric ...&#34;方法

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");

在EF 6中,这些应该是GetObjectSetName s:

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