11 Mayıs 2016 Çarşamba

Linq Expression Tree

Giriş
Yazıda Expression Tree yerine İfade Ağacı kelimesini kullanacağım. Linq ile kullandığımız lambda derleyici tarafından İfade Ağacı yapısına çevrilir. Bu yapıda kullanılan bazı sınıflar şöyle.

ParameterExpression
Bir metod çağrısına geçilecek parametreleri saklar.
PropertyInfo property = ... 
ParameterExpression pe = Expression.Parameter(typeof(string), property.Name);
Şöyle yaparız.
ParameterExpression pe = Expression.Parameter(typeof(T), "t");

MemberExpression
Açıklama yaz
Bir nesnenin property'sine erişmek için kullanılır. Dolayısıyla bir model yani erişilecek nesne bir de property generic parametresi alır. Şöyle bir yardımcı metodumuz olsun. Metodun içinde Expressin nesnesinin nasıl MemberExpression nesnesine çevrildiği görülebilir.
static class MemberExpressionHelper
{
  public static TProperty GetPropertyValue<TModel, TProperty>(TModel model, 
             Expression<Func<TModel, TProperty>> expression)
  {
    // case with `UnaryExpression` is omitted for simplicity
    var memberExpression = (MemberExpression)expression.Body;

    var propertyInfo = (PropertyInfo)memberExpression.Member;
    return (TProperty)propertyInfo.GetValue(model);
  }
}
Şöyle kullanırız.
var bar = MemberExpressionHelper.GetPropertyValue(foo, _ => _.Bar);

ConstantExpression
Sabit bir değeri saklar. Şöyle yaparız
string value = ...;
ConstantExpression ce = Expression.Constant(value, typeof(string));
Veya şöyle yaparız.
PropertyInfo property = ...
ConstantExpression ce = Expression.Constant(property.GetConstantValue());

MethodCallExpression
MethodCallExpression Sınıfı yazısına taşıdım.

Expression.Call
Açıklama yaz

Expression.Lambda
Tüm bu sınıflar bir araya gelerek bir Expression nesnesi oluşturuluyor. Bu nesne ise şöyle kullanılıyor.
IQueryable<T> query = ...;

Expression myexpression = ...;

Expression<Func<T, bool>> whereexpression = Expression.Lambda<Func<T, bool>>(
        myexpression, parameter);

return query.Where(expression);
BinaryExpression
Nesnenin sağ tarafına BinaryExpression olarak şöyle erişiriz.
Expression<Func<Foo, bool>> expr = p => p.Id == 2; // Supports even p.Id.Equals(2)
BinaryExpression be = expr.Body as BinaryExpression;
UnaryExpression Sınıfı
UnaryExpression Sınıfı yazısına taşıdım.

Hiç yorum yok:

Yorum Gönder