Dynamic table name in linq

c# entity-framework linq reflection


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.

7/16/2017 4:36:15 AM

Accepted Answer

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")
    .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

1/23/2015 8:13:34 AM

Related Questions


Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow