Dynamic table name in linq [duplicate]
I'm trying to execute some LINQ
commands using a dynamic table name. For example, instead of:
var o = (from x in context.users select x);
I want to use something like:
var o = (from x in getTableObjectByName("users", context) select x);
More or less. Here's the code I have so far, which both compiles and runs:
using (MySiteEntities ipe2 = new MySiteEntities()) {
var propinfo1 = Type.GetType("MySiteNamespace.MySiteEntities").GetProperty("users");
var propval1 = propinfo1.GetValue(ipe2, null);
}
That runs, but always returns zero records. The users table most definitely contains records, and in any case when I call it directly using the first method above I get all of the records as expected. How can I modify my code to actually pull down records, rather than just an empty collection?
Edit: I've also tried this:
using (MySiteEntities ipe = new MySiteEntities())
{
var prop = Type.GetType("MySiteNamespace.MySiteEntities").GetProperty("users");
Type dbsetType = typeof(DbSet<>);
dbsetType = dbsetType.MakeGenericType(Type.GetType("MySiteNamespace.user"));
Type t = dbsetType.GetType();
var val = prop.GetValue(ipe, null);
}
In this case, the code not only runs, but actually returns the results as expected. However, val
is an Object. I need to cast it to the type DbSet<user>
, which would be easy enough, except that the parameter user
is only known at runtime....the cast needs to be dynamic as well. I've tried using Convert.ChangeType(val, t);
, but that throws an
InvalidCastException (Object must implement IConvertible).
How can I convert the val
variable to an actually usable object?
No idea if this is relevant, but this is on EntityFramework 4.
Solution 1:
In your DbContext class, add a method say called Set that returns:
public DbSet Set(string name)
{
// you may need to fill in the namespace of your context
return base.Set(Type.GetType(name));
}
Which you can query like this:
using (var db = new YourDataContext())
{
// Since your DbSet isn't generic, you can can't use this:
// db.Set("Namespace.EntityName").AsQueryable().Where(a=> a.HasSomeValue...
// Your queries should also be string based.
// Use the System.Linq.Dynamic nuget package/namespace
var results = db.Set("Namespace.EntityName")
.AsQueryable()
.Where("SomeProperty > @1 and SomeThing < @2", aValue, anotherValue);
// you can now iterate over the results collection of objects
}
More information on System.Linq.Dynamic can be found here