54 votes

Entités PredicateBuilder C #: le paramètre 'f' n'était pas lié dans l'expression de requête LINQ to Entities spécifiée

J'ai besoin de construire un filtre dynamique et je voulais continuer à l'utiliser à des entités. Pour cette raison, je voulais utiliser le PredicateBuilder de albahari.

J'ai créé le code suivant:

var invoerDatums = PredicateBuilder.True<OnderzoeksVragen>();
var inner = PredicateBuilder.False<OnderzoeksVragen>();

foreach (var filter in set.RapportInvoerFilter.ToList())
{
    if(filter.IsDate)
    {
        var date = DateTime.Parse(filter.Waarde);
        invoerDatums = invoerDatums.Or(o => o.Van >= date && o.Tot <= date);
    }
    else
    {
        string temp = filter.Waarde;
        inner = inner.Or(o => o.OnderzoekType == temp);
    }
}

invoerDatums = invoerDatums.And(inner);
var onderzoeksVragen = entities.OnderzoeksVragen
                               .AsExpandable()
                               .Where(invoerDatums)
                               .ToList();

Quand j'ai couru le code il y avait seulement 1 filtre qui n'était pas un filtre de date. Si seulement l'intérieur de prédicat a été rempli. Lorsque le prédicat a été exécuté, j'ai obtenu l'erreur suivante.

Le paramètre " f " n'était pas lié à la spécifié requête LINQ to entities de l'expression.

Alors que la recherche d'une réponse que j'ai trouvé la suivante de la page. Mais ceci est déjà mis en œuvre dans le LINQKit.

Est-ce que quelqu'connu cette erreur et sait comment le résoudre?

122voto

Mant101 Points 1404

J'ai couru à travers la même erreur, la question semble être quand j'avais des prédicats fait avec PredicateBuilder qui ont été à leur tour d'autres prédicats fait avec PredicateBuilder

par exemple, (A OU B) ET (X OU Y), où un constructeur crée A OU B, on crée des X OU des Y et un troisième Padn ensemble.

Avec un seul niveau de prédicats AsExpandable a bien fonctionné, lorsque plus d'un niveau a été introduite j'ai eu le même message d'erreur.

Je n'étais pas en mesure de trouver de l'aide, mais à travers quelques essais et erreurs, j'ai été en mesure d'obtenir des choses à travailler. Chaque fois que j'ai appelé un prédicat je l'ai suivi avec l'expansion de la méthode d'extension.

Ici, c'est un peu le code, les couper vers le bas pour plus de simplicité:

public static IQueryable<Submission> AddOptionFilter(
    this IQueryable<Submission> query, 
    IEnumerable<IGrouping<int, int>> options)
{
    var predicate = options.Aggregate(
        PredicateBuilder.False<Submission>(),
        (accumulator, optionIds) => accumulator.Or(ConstructOptionMatchPredicate(optionIds).Expand()));
        query = query.Where(predicate.Expand());            
    return query;
}

La requête est un IQueryable qui a déjà eu AsExpandable appelé, ConstructOptionNotMatchPredicate renvoie une Expression.

Une fois que nous avons passé l'erreur nous étions certainement en mesure de construire des complexes de filtres lors de l'exécution à l'encontre de l'entity framework.

44voto

Chris Walsh Points 410

J'ai eu cette erreur et l'explication de Mant101 m'a donné la réponse, mais vous cherchez peut-être un exemple plus simple qui cause le problème:

 // This predicate is the 1st predicate builder
var predicate = PredicateBuilder.True<Widget>();

// and I am adding more predicates to it (all no problem here)
predicate = predicate.And(c => c.ColumnA == 1);
predicate = predicate.And(c => c.ColumnB > 32);
predicate = predicate.And(c => c.ColumnC == 73);

// Now I want to add another AND predicate with is actually comprises 
// of sub OR predicates
if(keywords.Length > 0)
{
    // NOTICE HERE: Here I am starting off a brand new 2nd predicate builder....
    // (not ANDing it to the existing one (yet))
    var subpredicate = PredicateBuilder.False<Widget>();

    foreach(string s in keywords)
    {
        string t = s;
        subpredicate = subpredicate.Or(c => c.Name.Contains(t));
    }

    // This is the "gotcha" bit... adding the ANDing the independent
    // sub-predicate to the 1st one....

    // If done like this, you will FAIL!
//  predicate = predicate.And(subpredicate); // FAIL at runtime!

    // To correct it, you must do this...
    predicate = predicate.And(subpredicate.Expand());  // OK at runtime!
}
 

J'espère que cela t'aides! :-)

0voto

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X