I am passing a string of the name of the entity type I want to query and getting the type based on the string. I want to get the DbSet
back and return an IQueryable
. The problem is where I am doing (DbSet<tableEntity>)
and getting the following error:
tableEntity is a variable but used like a type
when trying to cast. Is there a way to resolve this?
public object GetList(string tableEntity)
{
Type tableEntity = Type.GetType("TestProject." + typeName + ", TestProject");
var dbObject = (DbSet<tableEntity>)typeof(DbContext).GetMethod("Set", Type.EmptyTypes)
.MakeGenericMethod(tableEntity)
.Invoke(databaseContext, null);
return dbObject.AsQueryable();
}
EDIT
Just to add I don't have access to the type that's we I am passing the name through a string.
So it turns out that the entity type is literally not known, or knowable, at compile time. It has to be a string.
The only place you're using the type at compile time is in the cast to
(DbSet<tableEntity>)
. Well, you may not need that. All you need from that type is to callAsQueryable()
, andAsQueryable()
is an extension method forIEnumerable
, with generic and non-generic versions. IF we call it through non-genericIEnumerable
, that's non-genericAsQueryable()
, returning non-genericIQueryable
. But we're returningobject
anyway, so hey. For the result of this thing to be useful, something somewhere must be doing a fair amount of reflection on it anyway, so the declared type is likely to be of little consequence.See if this works:
If it turns out you need generic
IQueryable<TEntityType>
, we'll have to use reflection to getMethodInfo
forAsQueryable<TEntityType>
for the unknown (at compile time) entity type, and callMakeGenericMethod(tableEntity)
on that.First try:
In the language, type parameters to generics must be actual types, not instances of the
Type
class. That's because they're resolved at compile time.But that's no problem; to pass a type parameter to a generic method, simply write a generic method with a type parameter.
You can't do this:
But this is just as good:
...
Reflection is different; that's why we pass
typeof(TTableEntity)
toMakeGenericMethod()
.And once we're using an actual type that the compiler can check, we can do better with our return type, too:
Since, as Ed mentioned, you don't use the table entity type at compile time, why not just use the non-generic
databaseContext.Set (tableEntity).AsQueryable ()
? But if you've set your heart onSet<>
, try this: