Tworzenie w czasie wykonywania wyrażenia LINQ

Powiedz, że mam to wyrażenie:

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

W zasadzie „dzieli” zestaw elementów na 20 partycji i pobiera z każdego zestawu każdy pierwszy i czwarty element.

To wyrażenie jest przekazywane doMongoDB co to jestkierowca jest doskonale zdolny do tłumaczenia na „zapytanie” MongoDB. Predykat może jednak być również użyty na liście obiektów (LINQ2Objects) itp. Chcę, aby to wyrażenie było wielokrotnego użytku (SUCHY). Chcę jednak móc przejśćIEnumerable<int> aby określić, które przedmioty mają zostać pobrane (więc 1 i 4 nie są w nim „zakodowane na stałe”):

public Expression<Func<Foo, bool>> GetPredicate(IEnumerable<int> items) {
    //Build expression here and return it
}

ZLINQPad używając tego kodu:

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

Mogę zbadać wyrażenie:

Teraz chcę być w stanie zbudować dokładną reprodukcję tego wyrażenia, ale ze zmienną liczbą liczb całkowitych do przekazania (więc zamiast 1 i 4 mógłbym przejść, na przykład,[1, 5, 9, 11] lub[8] lub[1, 2, 3, 4, 5, 6, ..., 16]).

Próbowałem użyćBinaryExpressions itd., ale nie udało mi się poprawnie skonstruować tego komunikatu. Głównym problemem jest to, że większość moichpróbas nie powiedzie się podczas przekazywania predykatu do MongoDB.„Zakodowana” wersja działa dobrze ale jakoś wszystkie moje próby przekazania moich wyrażeń dynamicznych nie zostaną przetłumaczone na zapytanie MongoDB przez sterownik C #:

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

Zasadniczo chcę dynamicznie budować wyrażenie w środowisku wykonawczym w taki sposób, aby dokładnie replikowało to, co generuje kompilator dla „zakodowanej na stałe” wersji.

Każda pomoc zostanie doceniona.

EDYTOWAĆ

Zgodnie z prośbą w komentarzach (iopublikowane na pastebin), jedna z moich prób poniżej. Umieszczam to w pytaniu o odniesienie do futury, jeśli pastebin zdejmie je lub zatrzyma ich obsługę lub ...

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

To skutkuje:Unsupported where clause: <InvocationExpression>.

questionAnswers(1)

yourAnswerToTheQuestion