Dieser Artikel zeigt, wie zwei C# Ausdrücke vom Typ Expression<Func<bool>>
mit logischen und oder, und nicht von Operatoren kombiniert werden. Direkt ist die direkte Verwendung von Operatoren wie expr1 AND expr2
aufgrund von Parameterfehlanpassungen falsch. Es werden mehrere Ansätze vorgestellt, die jeweils unterschiedliche Szenarien behandeln.
Methode 1: Einfache Kombination (identische Parameter)
Wenn beide Ausdrücke denselben Parameter verwenden, besteht ein einfacher Ansatz darin, Expression.AndAlso
oder Expression.OrElse
direkt auf den Ausdruckskörpern zu verwenden:
1 2 | var body = Expression.AndAlso(expr1.Body, expr2.Body);
var lambda = Expression.Lambda<Func<bool>>(body, expr1.Parameters[0]);
|
Nach dem Login kopieren
Negation ist ähnlich einfach:
1 2 3 4 | static Expression<Func<bool>> Not<T>(this Expression<Func<bool>> expr)
{
return Expression.Lambda<Func<bool>>(Expression.Not(expr.Body), expr.Parameters[0]);
}
|
Nach dem Login kopieren
Methode 2: Kombinieren Ausdrücke mit unterschiedlichen Parametern mit Invoke
Wenn Ausdrücke unterschiedliche Parameter haben, kann die Invoke
-Methode verwendet werden, um einen neuen Lambda -Ausdruck mit einem gemeinsamen Parameter zu erstellen:
1 2 3 4 5 6 7 | static Expression<Func<bool>> AndAlso<T>(this Expression<Func<bool>> left, Expression<Func<bool>> right)
{
var param = Expression.Parameter(typeof(T), "x" );
var body = Expression.AndAlso(Expression.Invoke(left, param), Expression.Invoke(right, param));
var lambda = Expression.Lambda<Func<bool>>(body, param);
return lambda;
}
|
Nach dem Login kopieren
OrElse
wäre ähnlich und ersetzt AndAlso
durch OrElse
.
Methode 3: Optimierte Kombination (griff identische und verschiedene Parameter)
Diese Methode wählt intelligent den einfacheren Ansatz aus, wenn Parameter gleich sind, ansonsten verwendet Invoke
:
1 2 3 4 5 6 7 8 9 | static Expression<Func<bool>> AndAlso<T>(this Expression<Func<bool>> expr1, Expression<Func<bool>> expr2)
{
ParameterExpression param = expr1.Parameters[0];
if (ReferenceEquals(param, expr2.Parameters[0]))
{
return Expression.Lambda<Func<bool>>(Expression.AndAlso(expr1.Body, expr2.Body), param);
}
return Expression.Lambda<Func<bool>>(Expression.AndAlso(expr1.Body, Expression.Invoke(expr2, param)), param);
}
|
Nach dem Login kopieren
Methode 4: EF-Safe
Für Entity Framework -Kompatibilität bietet ein
eine robuste Lösung:
ExpressionVisitor
Diese Methode ersetzt Parameterreferenzen innerhalb der Ausdrücke, um die Kompatibilität mit verschiedenen LINQ -Anbietern sicherzustellen. Die Auswahl der Methode hängt von den spezifischen Anforderungen und dem Kontext Ihrer Anwendung ab, insbesondere von dem verwendeten LINQ -Anbieter und der Garantie der Parameterkonsistenz. Der
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | public static Expression<Func<bool>> AndAlso<T>(this Expression<Func<bool>> expr1, Expression<Func<bool>> expr2)
{
var parameter = Expression.Parameter(typeof(T));
var leftVisitor = new ReplaceExpressionVisitor(expr1.Parameters[0], parameter);
var left = leftVisitor.Visit(expr1.Body);
var rightVisitor = new ReplaceExpressionVisitor(expr2.Parameters[0], parameter);
var right = rightVisitor.Visit(expr2.Body);
return Expression.Lambda<Func<bool>>(Expression.AndAlso(left, right), parameter);
}
private class ReplaceExpressionVisitor : ExpressionVisitor
{
private readonly Expression _oldValue;
private readonly Expression _newValue;
public ReplaceExpressionVisitor(Expression oldValue, Expression newValue)
{
_oldValue = oldValue;
_newValue = newValue;
}
public override Expression Visit(Expression node)
{
if (node == _oldValue) return _newValue;
return base.Visit(node);
}
}
|
Nach dem Login kopieren
-Ansatz bietet die robusteste Lösung für komplexe Szenarien und Entitätsgerüstintegration.
ExpressionVisitor
Das obige ist der detaillierte Inhalt vonWie kann ich zwei Expressionsausdrücke mithilfe und oder nicht Operatoren in C#kombinieren?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!