3

目的:我需要获取实体typeof(UserAccount) = "UserAccounts"的dbset名称。但是在运行时我需要一个通用类型的循环,因此不知道示例“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; }
}

定义了一个类型列表来控制输出:

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”,因为我处于一系列类型的循环中。我只有类型列表给出 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;
}
4

1 回答 1

3

这里的挑战是涉及两个反射步骤,一个调用泛型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通过调用MethodInfo表示泛型方法来获得CreateObjectSet<T>()。然后我找到泛型类型PropertyInfo的属性。最后,我得到了这个属性的值和获得的.EntitySetObectSet<T>EntitySet

为此,我首先得到一个MethodInfofor CreateObjectSet<>()(没有参数的那个)和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 中,这些应该是usings:

using System.Data.Entity.Core.Metadata.Edm
using System.Data.Entity.Core.Objects
using System.Data.Entity.Infrastructure
using System.Linq
using System.Reflection
于 2014-10-19T00:04:36.743 回答