Search code examples
linq-to-entitiesentity-framework-5dynamic-dataauto-generate

Entity Framework Dynamic DbSet for all entities


I have a database mapped with Entity Framework,

I need to implement a generic method for getting a a list of items based on a parameter that I pass:

getGenericList("product"); // returns the list of products
getGenericList("customer"); // returns the list of customers

I need to dynamically get the dbSet. My method is implemented like this:

public static List<object> getGenericList(string entityType)
    {
        List<object> myDynamicList = new List<object>();
        using (cduContext db = new cduContext())
        {
            DbSet dbSet = db.getDBSet(entityType);
            var myDynamicList = dbSet.Select(p => p).ToList();
        }
        return new List<object>();
    }

my dbSets are auto-generated by EF code first :

public DbSet<Product> Products { get; set; }
public DbSet<Custommer> Custommers { get; set; }

my getDBSet(entityType) method is implemented in the context, like this:

public DbSet<T> getDBSet<T>(string entityName) where T : class
    {
        switch (entityName)
        {

            case "product":
                return Products;

            case "custommer":
                return Custommers;

I then got this error:

Cannot implicitly convert type 'System.Data.Entity.DbSet' to 'System.Data.Entity.DbSet'

Any Idea please !?

N.B. , the method Set() of the dbContext is not OK; the type should be explicitly given ...


Solution

  • To avoid the switch, you can lookup the Type by its assembly-qualified name, then get the DbSet from that. The DbSet retrieved this way is not generic<>, so the operations you can perform are more limited.

    You can get the assembly-qualified name by using a known entity type (e.g. Product), getting its assembly-qualified name, then replacing "Product" with the desired name to get the Type.

    This example is simplified from a Breeze app, in which certain lookup entities could be requested by name from the client.

    public async Task<List<object>> GetGenericList(string entityType)
    {
      using (var context = new MyContext())
      {
        var aqtemp = typeof(Product).AssemblyQualifiedName; // template for qualified name
    
        var aqname = aqtemp.Replace("Product", entityType); // qualified name for entityType
    
        var type = Type.GetType(aqname, true, true);      // Type for entityType
    
        var list = await context.Set(type).ToListAsync(); // query the entities
        return list;
      }
    }