DbContext.Set and DbContext.Set(string name) are the only available functions for EF Core. DbContext.Set(Type) is for Framework from what I have read. Knowing this limitation, we will be able to trigger this.
public List<Type> FetchDbSetTypes()
{
var properties = dbContext.GetType().GetProperties();
var dbSets = new List<Type>();
foreach (var property in properties)
{
var propertyType = property.PropertyType;
if(propertyType.IsGenericType && propertyType.Name.ToLower().Contains("dbset"))
{
Type dbSetType = propertyType.GenericTypeArguments[0]; //point of interest here
dbSets.Add(dbSetType);
}
}
return dbSets;
}
We now have a list of the DBSets' defined strong types. Next, we need to spoof the Set based on the added types. The only way to do this is to pass an object of that type as a parameter.
This requires reflection, InternalDbSet<>, DBContext, and dynamic.
List<Type> dbsetTypes = FetchDbSetTypes();
dbsetTypes.ForEach(async dbsetType =>
{
try
{
Type myType = typeof(InternalDbSet<>).MakeGenericType(dbsetType);
//instance is only used to spoof the binding
dynamic instance = Activator.CreateInstance(myType, context, dbsetType.Name);
var test = await FetchFromTable(instance, 0, 10);
}
catch(Exception)
{
//might fail due to other models
}
});
Then we call the generic method in question which takes DbSet
public async Task<List<T>> FetchFromTable<T>(DbSet<T> _, int skip = 0, int fetchSize = 10000) where T : class
{
//DbSet<T> parameter is not needed - it will throw an Exception
return await dbContext.Set<T>().Skip(skip).Take(fetchSize).ToListAsync();
}
Note: Make sure your DbContext properties have getters