我想使用Linq Expression树创建一个表达式来模拟这个:
List<int> ids = new List<int>();
// Fill ids with data
db.Where(a => ids.Contains(a.Id));
这是我得到的地方,但我仍然遗漏了一些东西:
MemberExpression me = Expression.Property(pe, typeof(T).GetProperty(property));
Expression callContains = Expression.Call(typeof(System.Linq.Enumerable), "Contains", new Type[] { me.Type }, me);
我怎样才能做我想做的事?
答案 0 :(得分:12)
由于Contains
是一种扩展方法,因此您还必须将ids
集合作为参数提供,在本例中为ConstantExpression
。
您的实现可能略有不同,但看起来有点像这样:
public static IQueryable<T> DynamicContains<T, TProperty>(
this IQueryable<T> query,
string property,
IEnumerable<TProperty> items)
{
var pe = Expression.Parameter(typeof(T));
var me = Expression.Property(pe, property);
var ce = Expression.Constant(items);
var call = Expression.Call(typeof(Enumerable), "Contains", new[] { me.Type }, ce, me);
var lambda = Expression.Lambda<Func<T, bool>>(call, pe);
return query.Where(lambda);
}
db.DynamicContains("Id", ids);
答案 1 :(得分:0)
您可以添加对Mono.CSharp dll的引用,然后您可以使用Evaluator类来动态编译csharp代码 然后连接字符串以轻松创建linq查询 然后编译它们 它不慢,而且很容易
答案 2 :(得分:0)
作为@ p-s-w-g答案的补充,动态不包含:
public static IQueryable<T> DynamicNotContains<T, TProperty>(this IQueryable<T> query, string property, IEnumerable<TProperty> items)
{
var pe = Expression.Parameter(typeof(T));
var me = Expression.Property(pe, property);
var ce = Expression.Constant(items);
var call = Expression.Call(typeof(Enumerable), "Contains", new[] { me.Type }, ce, me);
var lambda = Expression.Lambda<Func<T, bool>>(Expression.Not(call), pe);
return query.Where(lambda);
}
db.DynamicNotContains("Id", ids);