How do I select correct DbSet in DbContext based on table name

17,555

Solution 1

You can get DbSet from DbContext by Type using the method DbContext.Set(Type entityType). So if you have the model class name as string you should do some mapping to actual clr type.

For example:

string tableName = "Cat";
var type = Assembly.GetExecutingAssembly()
        .GetTypes()
        .FirstOrDefault(t => t.Name == tableName);

DbSet catContent;
if(type != null)
    catContext = context.Set(type);

You also can get type from string using Full Assembly Qualified Name Type.GetType(' ... ')

If will be even easier if you can store configurations somehow in generic way and use the generic context.Set<T>() method.

Solution 2

Another approach is below and work fine for me:

Type t = Type.GetType(Assembly.GetExecutingAssembly().GetName().Name + "." + "TableName");
DbSet dbset = dbcontext.Set(t);
Share:
17,555
DobleA
Author by

DobleA

evil computer scientist in the making

Updated on June 11, 2022

Comments

  • DobleA
    DobleA almost 2 years

    Say I have a DbContext with the following DbSets

    class Amimals : DbContext
    {
        public DbSet<Dog> Dogs { get; set; }
        public DbSet<Cat> Cats { get; set; }
    }
    

    Inside of each EntityTypeConfiguration I am defining the table for each DbSet like

    class DogConfig : EntityTypeConfiguration
    {
        public DogConfig()
        {
            this.ToTable("DOG_TABLE");
            ...
        }
    }
    

    Now, if I have the table name and the DbContext, how can I grab and use the correct DbSet?

    void foo()
    {
        string tableName = this.GetTableName();
        using(Animals context = new Animals())
        {
            /* Made up solution */
            DbSet animalContext = context.Where(c => c.TableName == tableName);
            ...
            /* Do something with DbSet */
            ...
        }
    }
    
  • DobleA
    DobleA over 9 years
    Well, this is returning the EntityTypeConfiguration class. I need to use the DbSet. Is there a way to get the instance of the DbSet inside the context?
  • Viktor Bahtev
    Viktor Bahtev over 9 years
    Yes, you can. This code works just fine and returns an instance of DbSet. In my example 'talbeName' must match the model class name. Please note that 'tableName' is equal to "Cat" so the result will be DbSet<Cat>. Ok, 'tableName' sounds somehow unclear it should be 'c# model class name which is used in DbContext generic DbSet with this type and represents some table name'. Please share your not working code.
  • DobleA
    DobleA over 9 years
    Well, I can't call Linq methods to the DbSet like I could if I said context.Cats.Select(c => c) I tried using AsQueryable() but that still doesn't do it
  • DobleA
    DobleA over 9 years
    msdn.microsoft.com/en-us/library/… says that context.Set(type) returns a non-generic DbSet instance. If I type context.Set<Cat>() I can actually call linq methods for the returned DbSet. Is there a way I can use the <> way?
  • Dockstar
    Dockstar about 7 years
    Have you tried Casting the result to a DBSet<TargetClass> on the generic? Not sure if it would work without some basic testing.
  • Ali
    Ali almost 7 years
    @Dobela Could please share to us that have you got resualt in use <> ? I have this problem too
  • Deadpool
    Deadpool over 5 years
    Side note: while this approach works fine on Entity Framework, it's not working on Entity Framework Core, though. For EF Core I found this approach very useful. Hope someone else can find this comment useful as well!
  • Amir978
    Amir978 almost 3 years
    Thanks for your answer, I tried it but entityType is Null, so the next line throws the error: System.Reflection.AmbiguousMatchException Ambiguous match found
  • Amir978
    Amir978 almost 3 years
    Error CS0411: The type arguments for method 'method' cannot be inferred from the usage. Try specifying the type arguments explicitly.
  • Matt
    Matt almost 3 years
    @Amir978 Just guessing, but you might have two class with the same name in a different space.
  • Bamdad
    Bamdad almost 3 years
    @Amir978 You are using Entity Framework Core (EF Core). The question is about Entity Framework (probably EF 6).
  • Michael Mairegger
    Michael Mairegger over 2 years
    @Amir978 No the issue is because there are two Set methods. Set<T>() and Set<T>(string) What worked for me was querying for: ...GetMethods().First(e => e.Name == "Set" && e.IsGenericMethod)