EF gets dbset name at runtime from type

Purpose: I need to get the dbset name of an object typeof (UserAccount) = "UserAccounts". But at runtime, I need a generic type for the loop, and therefore don't know an example "UserAccount". Just "name" from typeof?

I created a DbContext with some objects. I've been searching the web for a long time, but it doesn't seem to work for me due to type conversion?

At the bottom of this description, you can see my GetDbSetName method .

I'm new to this EF stuff, so please help with my problem as explained below :-)

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

      

Defined list Type for output control:

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

      

The problem is below using Type . If I use "UserAccount" it works and I get "UserAccounts". But I don't have a "UserAccount" at runtime as I am in a loop with a series of types. I only have a list of types indicating e

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

      

HERE IS THE METHOD THAT GIVES ME SHALLANDS; -) The meaning is not compilation. saying I'm missing an assembly? I know this is pretty pseudo, but can this be done smoothly?

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

      

+3


source to share


1 answer


The challenge here is that there are two stages of reflection involved, one to call the general method CreateObjectSet

and one to get the EntitySet

result. Here's how to do it:

Method first:

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

      

As you can see, I first get ObjectSet

by calling the MethodInfo

representing the generic method CreateObjectSet<T>()

. Then I find PropertyInfo

for the property of the EntitySet

typical type ObectSet<T>

. Finally, I get this property value and the name of the resulting one EntitySet

.

To do this, I first get MethodInfo

for CreateObjectSet<>()

(the one with no parameters) and the typeObjectSet<>



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

      

In GetObjectSetName

their general parameters are specific type of object, which is performed by these methods "MakeGeneric ...".

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

      

In EF 6, these should be 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

      

+2


source







All Articles