linq中的动态表名 [英] Dynamic table name in linq
问题描述
我正在尝试使用动态表名执行一些 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( 用户)。
键入dbsetType = typeof(DbSet<>);
dbsetType = dbsetType.MakeGenericType(Type.GetType(MySiteNamespace.user));
类型t = dbsetType.GetType();
var val = prop.GetValue(ipe,null);
}
在这种情况下,代码不仅运行,而且实际返回结果为预期。但是, val
是一个对象。我需要将它转换为类型 DbSet< user>
,这将很容易,除了参数 user
只是在运行时才知道...演员也需要动态。我尝试使用 Convert.ChangeType(val,t);
,但是会抛出一个
InvalidCastException(Object必须实现IConvertible)。
如何转换 val
变量到一个实际可用的对象?
不知道这是否相关,但这是在EntityFramework 4。
在您的DbContext类中,添加一种称为Set的方法,返回:
public DbSet Set(string name)
{
//你可能需要填写上下文的命名空间
return base.Set(Type.GetType(name));
}
您可以这样查询:
using(var db = new YourDataContext())
/ pre>
{
//由于您的DbSet不是通用的,因此您无法使用这个:
// db.Set(Namespace.EntityName)。AsQueryable()。Where(a => a.HasSomeValue ...
//你的查询也应该是基于字符串的
//使用System.Linq.Dynamic nuget包/命名空间
var results = db.Set(Namespace.EntityName)
.AsQueryable()
.Where(SomeProperty < @ 1和SomeThing< @ 2,aValue,anotherValue);
//你现在可以遍历对象的结果集
}
有关System.Linq.Dynamic的更多信息,请参见 here
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 typeDbSet<user>
, which would be easy enough, except that the parameteruser
is only known at runtime....the cast needs to be dynamic as well. I've tried usingConvert.ChangeType(val, t);
, but that throws anInvalidCastException (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.
解决方案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
这篇关于linq中的动态表名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!