Dynamic table name in linq

17,704

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

Share:
17,704
Russell Uhl
Author by

Russell Uhl

Updated on June 04, 2022

Comments

  • Russell Uhl
    Russell Uhl almost 2 years

    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.