LINQ中动态表名

5

我正在尝试使用动态表名执行一些LINQ命令。例如,不是:

var o = (from x in context.users select x);

我想使用类似这样的东西:

var o = (from x in getTableObjectByName("users", context) select x);

多多少少。这是我目前为止编写的代码,它可以编译和运行:

using (MySiteEntities ipe2 = new MySiteEntities()) {
    var propinfo1 = Type.GetType("MySiteNamespace.MySiteEntities").GetProperty("users");
    var propval1 = propinfo1.GetValue(ipe2, null);
}

代码可以运行,但总是返回零条记录。用户表明确包含记录,而且无论如何,当我使用上述第一种方法直接调用它时,我会得到所有预期的记录。如何修改我的代码以实际拉下记录,而不仅仅是一个空集合?

编辑:我也尝试过这个:

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);
}

在这种情况下,代码不仅可以运行,而且实际上返回了预期的结果。然而,val是一个对象。我需要将其转换为类型DbSet<user>,这应该很容易,但是参数user只在运行时才知道...所以强制转换也需要是动态的。我尝试过使用Convert.ChangeType(val, t);,但是这会抛出一个

InvalidCastException (Object must implement IConvertible)。

怎样才能将变量val转换为实际可用的对象呢?不确定这是否相关,但这是在EntityFramework 4上进行的。

那么automapper或者Dynamic Lync怎么样? - Murray Foxcroft
泛型类型在编译时已知。当编译时不存在泛型类型时,您不能在运行时动态地将其强制转换为泛型类型,除非您通过反射构建对象。 - Gert Arnold
1个回答

6
在您的DbContext类中,添加一个名为Set的方法,该方法返回:
public DbSet Set(string name)
{
  // you may need to fill in the namespace of your context
  return base.Set(Type.GetType(name));
}

您可以像这样查询它:
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
}

有关System.Linq.Dynamic的更多信息,请访问此处


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接