12 Mart 2018 Pazartesi

Expression.Parameter metodu

Giriş
Bir metoda geçilen parametre nesnesine erişmek için kullanılır.

Örnek
Şöyle yaparız.
static class IdFetcher<T>
{
  public static int Fetch(T item) => fetch(item);
  static readonly Func<T, int> fetch;
  static IdFetcher()
  {
    var p = Expression.Parameter(typeof(T), "item");
    fetch = Expression.Lambda<Func<T, int>>(
      Expression.PropertyOrField(p, "Id"), p).Compile();
  }
}
Çağırmak için şöyle yaparız
int n = IdFetcher<T>IdFetcher<T>.Fetch(obj);
Örnek
Şöyle yaparız.
ParameterExpression param = Expression.Parameter(typeof(T), "t");
Örnek
Şöyle yaparız.
var param = Expression.Parameter(typeof(int), "n");
Örnek
Boat nesnesi ve buna ait Accounts listesi olsun. Elimizde bir lambda olsun
repo = repo.Where(x => x.Accounts.FirstOrDefault().Id == AccountId);
Şöyle yaparız. x nesnesi ile bir Expression oluştururuz. Bu nesnenin "Accounts" alanına erişiriz.
var parameterExp = Expression.Parameter(typeof(Boat), "x");
Expression propertyExp = Expression.Property(parameterExp, "Accounts");

Type elementType = propertyExp.Type.GetGenericArguments()[0];

MethodInfo method1 = typeof(Enumerable).GetMethods(
BindingFlags.Public | BindingFlags.Static).First(m => m.Name == "FirstOrDefault");

// This gives me a Queryable of Account FirstOrDefault
var specificMethod = method1.MakeGenericMethod(elementType);


var firstOrDefaultAccountExpression = Expression.Call(specificMethod, propertyExp);

var idExpr = Expression.PropertyOrField(firstOrDefaultAccountExpression, "Id");

MethodInfo method = typeof(long).GetMethod("Equals", new[] { typeof(long) });
var someValue = Expression.Constant(AccountId, typeof(long));
var containsMethodExp = Expression.Call(idExpr, method, someValue);

Expression<Func<Boat, bool>> predicate = Expression.Lambda<Func<Boat, bool>>
             (containsMethodExp, parameterExp);

repo = repo.Where(predicate);

Hiç yorum yok:

Yorum Gönder