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);
Comments
-
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 over 9 yearsWell, 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 over 9 yearsYes, 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 over 9 yearsWell, I can't call Linq methods to the DbSet like I could if I said
context.Cats.Select(c => c)
I tried usingAsQueryable()
but that still doesn't do it -
DobleA over 9 yearsmsdn.microsoft.com/en-us/library/… says that
context.Set(type)
returns a non-generic DbSet instance. If I typecontext.Set<Cat>()
I can actually call linq methods for the returned DbSet. Is there a way I can use the<>
way? -
Dockstar about 7 yearsHave you tried Casting the result to a DBSet<TargetClass> on the generic? Not sure if it would work without some basic testing.
-
Ali almost 7 years@Dobela Could please share to us that have you got resualt in use
<>
? I have this problem too -
Deadpool over 5 yearsSide 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 almost 3 yearsThanks for your answer, I tried it but entityType is Null, so the next line throws the error: System.Reflection.AmbiguousMatchException Ambiguous match found
-
Amir978 almost 3 yearsError CS0411: The type arguments for method 'method' cannot be inferred from the usage. Try specifying the type arguments explicitly.
-
Matt almost 3 years@Amir978 Just guessing, but you might have two class with the same name in a different space.
-
Bamdad almost 3 years@Amir978 You are using
Entity Framework Core (EF Core)
. The question is aboutEntity Framework
(probably EF 6). -
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)