的说我有以下表达式:运行时创建LINQ表达
int setsize = 20;
Expression<Func<Foo, bool>> predicate = x => x.Seed % setsize == 1
|| x.Seed % setsize == 4;
这基本上'分区的一组元素到20个分区的,并且从每个设置的每个第一和第四元件检索。
该表达式被传递给MongoDB,它是driver完全能够翻译成MongoDB“查询”。但是,谓词也可以用于对象列表(LINQ2Objects)等。我希望此表达式可以重用(DRY)。不过,我希望能够在IEnumerable<int>
传递给指定要检索的项目(所以1和4不“硬编码”到它):
public Expression<Func<Foo, bool>> GetPredicate(IEnumerable<int> items) {
//Build expression here and return it
}
随着LINQPad使用此代码:
int setsize = 20;
Expression<Func<Foo, bool>> predicate = x => x.Seed % setsize == 1 || x.Seed % setsize == 4;
predicate.Dump();
}
class Foo
{
public int Seed { get; set; }
我可以检查表达:
现在,我希望能够建立这种表达的真实再现,但与可变数量的整数通过(所以,而不是1和4我可以通过,例如,[1, 5, 9, 11]
或[8]
或[1, 2, 3, 4, 5, 6, ..., 16]
)。
我试过使用BinaryExpressions等,但一直无法正确构造此消息。主要问题是我的attempt的大多数在将谓词传递给MongoDB时会失败。 的“硬编码”版本工作正常但不知何故,所有我试图通过我的动态表情无法被翻译成由C#驱动程序的MongoDB查询:
{
"$or" : [{
"Seed" : { "$mod" : [20, 1] }
}, {
"Seed" : { "$mod" : [20, 4] }
}]
}
基本上,我要动态地构建在运行时的表达以这种方式,它完全复制了编译器为“硬编码”版本生成的内容。
任何帮助将不胜感激。
编辑
As requested in the comments(和posted on pastebin),下面我尝试之一。我张贴在furure参考问题应该引擎收录把它记下来或停止其serivce或...
using MongoRepository;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
class Program
{
static void Main(string[] args)
{
MongoRepository<Foo> repo = new MongoRepository<Foo>();
var reporesult = repo.All().Where(IsInSet(new[] { 1, 4 }, 20)).ToArray();
}
private static Expression<Func<Foo, bool>> IsInSet(IEnumerable<int> seeds, int setsize)
{
if (seeds == null)
throw new ArgumentNullException("s");
if (!seeds.Any())
throw new ArgumentException("No sets specified");
return seeds.Select<int, Expression<Func<Foo, bool>>>(seed => x => x.Seed % setsize == seed).JoinByOr();
}
}
public class Foo : Entity
{
public int Seed { get; set; }
}
public static class Extensions
{
public static Expression<Func<T, bool>> JoinByOr<T>(this IEnumerable<Expression<Func<T, bool>>> filters)
{
var firstFilter = filters.First();
var body = firstFilter.Body;
var param = firstFilter.Parameters.ToArray();
foreach (var nextFilter in filters.Skip(1))
{
var nextBody = Expression.Invoke(nextFilter, param);
body = Expression.Or(body, nextBody);
}
return Expression.Lambda<Func<T, bool>>(body, param);
}
}
这导致:Unsupported where clause: <InvocationExpression>
。
请显示一些 - 或者至少一个 - 你的尝试。 –
这里你去:http://pastebin.com/qDwXGGit。这导致:'Unsupported where clause:'。 –
RobIII