c# - sintaxis - no se encontró ninguna implementación del patrón de consulta para el tipo de origen
C#PredicateBuilder Entities: el parámetro ''f'' no estaba enlazado en la expresión de consulta LINQ to Entities especificada (2)
Necesitaba construir un filtro dinámico y quería seguir usando entidades. Por esta razón, quería usar PredicateBuilder de albahari.
Creé el siguiente código:
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();
Cuando ejecuté el código solo había 1 filtro que no era un filtro de fecha. Entonces solo el predicado interno se llenó. Cuando se ejecutó el predicado, recibí el siguiente error.
El parámetro ''f'' no estaba vinculado en la expresión de consulta LINQ to Entities especificada.
Mientras buscaba una respuesta, encontré la siguiente page . Pero esto ya está implementado en el LINQKit.
¿Alguien más ha experimentado este error y sabe cómo resolverlo?
Me encontré con el mismo error, el problema parecía ser cuando tenía predicados hechos con PredicateBuilder que a su vez estaban formados por otros predicados hechos con PredicateBuilder
por ejemplo, (A O B) AND (X o Y) donde un constructor crea A o B, uno crea X o Y y un tercero AND juntos.
Con solo un nivel de predicados AsExpandable funcionó bien, cuando se introdujo más de un nivel recibí el mismo error.
No pude encontrar ninguna ayuda, pero a través de una prueba y error pude hacer que las cosas funcionen. Cada vez que llamé a un predicado lo seguí con el método de extensión Expandir.
Aquí hay un poco del código, reducido para simplificar:
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;
}
Query es un IQueryable al que ya se le ha llamado AsExpandable, ConstructOptionNotMatchPredicate devuelve una Expresión.
Una vez que superamos el error, pudimos construir filtros complicados en tiempo de ejecución contra el marco de la entidad.
Editar:
Debido a que las personas todavía comenten y votan, supongo que todavía es útil, así que estoy compartiendo otra solución. Básicamente, he dejado de usar LinqKit y su creador de predicados a favor de este Universal Predicate Builder que tiene la misma API pero no necesita Expandir llamadas, vale la pena echarle un vistazo.
Recibí este error y la explicación de Mant101 me dio la respuesta, pero es posible que esté buscando un ejemplo más simple que cause el problema:
// 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 which actually comprises
// of a whole list of sub-"OR" predicates
if(keywords.Length > 0)
{
// NOTICE: Here I am starting off a brand new 2nd predicate builder....
// (I''m not "AND"ing it to the existing one (yet))
var subpredicate = PredicateBuilder.False<Widget>();
foreach(string s in keywords)
{
string t = s; // s is part of enumerable so need to make a copy of it
subpredicate = subpredicate.Or(c => c.Name.Contains(t));
}
// This is the "gotcha" bit... 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!
}
¡Espero que esto ayude! :-)