Ä°ki ifadeyi (Ä°fade<Ä°ÅŸlev<T, bool>>)birleÅŸtiren
6 ** iki tip ifadeler var YA, al VE ya bu DEĞİL ve aynı türde yeni bir ifade almak istiyorum
Expression<Func<T, bool>> expr1;
Expression<Func<T, bool>> expr2;
...
//how to do this (the code below will obviously not work)
Expression<Func<T, bool>> andExpression = expr AND expr2
CEVAP
Ä°yi, Expression.AndAlso
/ OrElse
vb mantıksal ifadeleri birleştirmek için kullanabilirsiniz, ama sorun parametreleri; expr1 ve expr2 ParameterExpression
aynı çalışma misin? Eğer öyleyse, bu kolaydır:
var body = Expression.AndAlso(expr1.Body, expr2.Body);
var lambda = Expression.Lambda<Func<T,bool>>(body, expr1.Parameters[0]);
Bu da tek bir işlemle inkar etmeye çalışır:
static Expression<Func<T, bool>> Not<T>(
this Expression<Func<T, bool>> expr)
{
return Expression.Lambda<Func<T, bool>>(
Expression.Not(expr.Body), expr.Parameters[0]);
}
Aksi takdirde, SERİ sağlayıcısına bağlı olarak, Invoke
ile onları birleştirmek mümkün olabilir:
// OrElse is very similar...
static Expression<Func<T, bool>> AndAlso<T>(
this Expression<Func<T, bool>> left,
Expression<Func<T, 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<T, bool>>(body, param);
return lambda;
}
Bir yerlerde, ben bir kod yeniden yazma bir ifade ağacı yerine düğümleri kaldırmak lazım Invoke
, ama oldukça uzun (ve ben hatırlayamıyorum koymuş gibi...)
Genelleştirilmiş en basit yolu seçer sürüm:
static Expression<Func<T, bool>> AndAlso<T>(
this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
// need to detect whether they use the same
// parameter instance; if not, they need fixing
ParameterExpression param = expr1.Parameters[0];
if (ReferenceEquals(param, expr2.Parameters[0]))
{
// simple version
return Expression.Lambda<Func<T, bool>>(
Expression.AndAlso(expr1.Body, expr2.Body), param);
}
// otherwise, keep expr1 "as is" and invoke expr2
return Expression.Lambda<Func<T, bool>>(
Expression.AndAlso(
expr1.Body,
Expression.Invoke(expr2, param)), param);
}
Başlatılmasını .net 4.0. EF güvenli olan ifadeleri oluşturmak için izin ExpressionVistor sınıfı var.
public static Expression<Func<T, bool>> AndAlso<T>(
this Expression<Func<T, bool>> expr1,
Expression<Func<T, 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<T, 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);
}
}
Neden İfade<İşlev<T> kullanırs...
Neden Ä°ÅŸlev<T,bool > Predicate< y...
bir dönüştürme .net İşlev<T&; gt iç...
İfade<İşlev< arasındaki fark;>...
En iyi durum ifade null bool kontrol e...