Создание во время выполнения выражения LINQ

Скажи, у меня есть это выражение:

int setsize = 20;
Expression<Func<Foo, bool>> predicate = x => x.Seed % setsize == 1
                                          || x.Seed % setsize == 4;

Это в основном «разбивает» набор элементов на 20 разделов и извлекает из каждого набора каждый первый и четвертый элемент.

Это выражение передаетсяMongoDB что этоВодитель вполне способен переводить в 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 и т.д., но не смогли правильно сконструировать это сообщение. Основная проблема заключается в том, что большинство моихпопыткаСбой при передаче предиката в MongoDB.«Жестко» версия работает нормально но почему-то все мои попытки передать мои динамические выражения не могут быть преобразованы в запрос MongoDB драйвером C #:

{
    "$or" : [{
        "Seed" : { "$mod" : [20, 1] }
    }, {
        "Seed" : { "$mod" : [20, 4] }
    }]
}

По сути, я хочу динамически построить выражение во время выполнения таким образом, чтобы оно точно копировало то, что генерирует компилятор для «жестко закодированной» версии.

Любая помощь будет оценена.

РЕДАКТИРОВАТЬ

Как и просили в комментариях (а такжеразмещено на pastebin), одна из моих попыток ниже. Я выкладываю это в вопросе для справки о будущем, должен ли Пастбин снять его или прекратить их обслуживание или ...

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 pa,ram = 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>.

Ответы на вопрос(1)

Ваш ответ на вопрос