Expression.Or, Die parameter 'item' is nie in omvang
-
03-07-2019 - |
Vra
Ek probeer om 'n statiese funksie of twee uitdrukkings skryf, maar ontvang die volgende fout:
Die parameter 'item' is nie in omvang.
Description: 'n verwerkte uitsondering plaasgevind het tydens die uitvoering van die huidige web versoek. Gaan asseblief die stapel spoor vir meer inligting oor die fout en waar dit sy oorsprong in die kode.
Uitsondering Besonderhede: System.InvalidOperationException: Die parameter 'item' is nie in omvang.
die metode:
public static Expression<Func<T, bool>> OrExpressions(Expression<Func<T, bool>> left, Expression<Func<T, bool>> right)
{
// Define the parameter to use
var param = Expression.Parameter(typeof(T), "item");
var filterExpression = Expression.Lambda<Func<T, bool>>
(Expression.Or(
left.Body,
right.Body
), param);
// Build the expression and return it
return (filterExpression);
}
wysig : die toevoeging van meer inligting
Die uitdrukkings word or'd kom uit die onderstaande metode, wat uit te voer net 'n boete. indien daar 'n beter manier om of die resultate is ek die ene ore. Ook, ek weet nie hoeveel word or'd in advance.
public static Expression<Func<T, bool>> FilterExpression(string filterBy, object Value, FilterBinaryExpression binaryExpression)
{
// Define the parameter to use
var param = Expression.Parameter(typeof(T), "item");
// Filter expression on the value
switch (binaryExpression)
{
case FilterBinaryExpression.Equal:
{
// Build an expression for "Is the parameter equal to the value" by employing reflection
var filterExpression = Expression.Lambda<Func<T, bool>>
(Expression.Equal(
Expression.Convert(Expression.Property(param, filterBy), typeof(TVal)),
Expression.Constant(Value)
),
param);
// Build the expression and return it
return (filterExpression);
}
wysig : die toevoeging van nog meer inligting
As alternatief is daar 'n beter manier om 'n of doen? Tans is die .Where (dwang) werk net mooi waar beperking is van tipe Expression>. Hoe kan ek doen waar (constraint1 of constraint2) (die beperking n'th)
Dankie by voorbaat!
Oplossing
Die probleem is dat die Expression jy skep in die metode OrExpressions reuses die liggaam van die twee uitdrukkings. Diegene liggame sal verwysings na hul eie ParameterExpression wat gedefinieer het in FilterExpression bevat.
'n fix sou wees om die links en regs dele herskryf om die nuwe ParameterExpression gebruik. Of om die oorspronklike ParameterExpression saam te slaag. Dit is nie omdat die twee ParameterExpression het dieselfde naam wat hulle dieselfde parameter verteenwoordig.
Ander wenke
Soos reeds voorgestel, hier jy hierdie baie mooi (werk) kode kan vind
public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2)
{
var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
return Expression.Lambda<Func<T, bool>>(Expression.Or(expr1.Body, invokedExpr), expr1.Parameters);
}
wat jy kan aanpas by jou behoeftes en wat nie gekoppel is (IMHO) na LINQ.
Ek is nie seker oor die korrekte terme hier, maar basies uitdrukking parameters is nie ekwivalent selfs al het hulle dieselfde naam.
Dit beteken dat
var param1 = Expression.Parameter(typeof(T), "item");
var param2 = Expression.Parameter(typeof(T), "item");
param1 != param2
PARAM1 en PARAM2 sal nie dieselfde ding wees as dit gebruik word in 'n uitdrukking.
Die beste manier om te gaan met dit skep 'n parameter aan die voorkant vir jou uitdrukking, en dan slaag dit aan al helper funksies wat die parameter nodig het.
EDIT: En as jy probeer om dinamies te komponeer waar klousules in LINQ, jy kan gee PredicateBuilder 'n drie.
Vir diegene wat hierdie bladsy gevind deur 'n soektog en gaan die PredicateBuilder gebruik van Ben & Joe Albahari , kyk uit, want dit nie werk met die Entiteit Raamwerk .
Probeer hierdie vaste weergawe plaas.
Fabrizio se oplossing het ook voorgekom om my so goed, maar sedert ek probeer om twee uitdrukkings wat uitgevoer sal word as 'n linQ 2 sql query kombineer, het ek gedink dit sou doen in die geheue in plaas van die SQL Server.
Ek is geskryf -. Linq-To-Sql erken dat die aanroeping is van 'n lambda uitdrukking en dus nog produseer new sql