2011-07-09 13 views
1

私は基本的にそれがこの表現をどのように拡張しますか?

p => p.fieldname.StartsWith("123") 

しかし、私はこのような何かを行うには、この上で拡大するを吐き出し、一例として、コードのこのビットを持っている:ここでは

p => p.anotherentity.fieldname.StartsWith("123") 

はコードのサンプルです私は自分のニーズに合わせてリファクタリングしていています:

string propertyName = "FirstName"; 
string methodName = "StartsWith"; 
string keyword = "123"; 

Type t = typeof (Person); 

ParameterExpression paramExp = Expression.Parameter(t, "p"); 
// the parameter: p 

MemberExpression memberExp = Expression.MakeMemberAccess(paramExp, 
                 t.GetMember(propertyName).FirstOrDefault()); 
// part of the body: p.FirstName 

MethodCallExpression callExp = Expression.Call(memberExp, 
               typeof (string).GetMethod(methodName, 
                     new Type[] {typeof (string)}), 
               Expression.Constant(keyword)); 
// the body: p.FirstName.StartsWith("123") 

Expression<Func<Person, bool>> whereExp = Expression.Lambda<Func<Person, bool>>(callExp, paramExp); 
Expression<Func<Person, string>> selectExp = Expression.Lambda<Func<Person, string>>(memberExp, paramExp); 

Console.WriteLine(whereExp); // p => p.FirstName.StartsWith("123") 
Console.WriteLine(selectExp); // p => p.FirstName 

をさらに私を聞かせて説明するために私がやりたい何を示しています。

public class Person 
{ 
    public string IdentityCode {get;set;} 
    public Loans Loans {get;set;} 
} 

public class Loans 
{ 
    public int Id {get;set;} 
    public Asset Assets {get;set;} 
    public Person person {get;set;} 
} 

public class Asset 
{ 
    public string SerialNumber {get;set;} 
} 

その後、式を使用して、このような何か構築:テストされていない

p => p.Loans.Asset.SerialNumber.StartsWith("123) 

それとも

p => p.Loans.Person.IdentityCode.StartsWith("123") 

答えて

0

すでに既存の、古い表現を持って、それを更新したい場合は、私は...

あなたは、を求める式を更新するか、ゼロから1を構築しているかわからないんだけど、それは新しいものを作成するのは非常に簡単です。考え方は、式ツリーを置き換えて置き換える式に至るまで掘り下げることです。その後、すべての親表現を新しく置換したもので更新します。

Expression<Func<Person, bool>> expr = 
    p => p.Loans.Asset.SerialNumber.StartsWith("123"); 

は最初からそれをうまく:それ以外の場合は式ツリーを構築する

Expression<Func<Obj, bool>> expr = p => p.fieldname.StartsWith("123"); 
var body = expr.Body as MethodCallExpression; // *.StartsWith() 
var obj = body.Object as MemberExpression;  // p.fieldname 
var param = expr.Parameters.First();   // p 
var newAccess = Expression.PropertyOrField(param, "anotherentity"); // p.anotherentity 
var newObj = obj.Update(newAccess);     // update obj 
var newBody = body.Update(newObj, body.Arguments); // update body 
var newExpr = expr.Update(newBody, expr.Parameters);// update expr 

var p = Expression.Parameter(typeof(Person), "p"); 
var accessLoans = Expression.PropertyOrField(p, "Loans"); 
var accessAsset = Expression.PropertyOrField(accessLoans, "Asset"); 
var accessSerialNumber = Expression.PropertyOrField(accessAsset, "SerialNumber"); 
var callArgs = new Expression[] { Expression.Constant("123", typeof(string)) }; 
var callStartsWith = Expression.Call(accessSerialNumber, "StartsWith", null, callArgs); 
var newExpr = Expression.Lambda<Func<Person, bool>>(callStartsWith, p); 

私は練習問題として最後の1つを残します。

+0

ありがとう、これはまさに私が後だったものです:) – xqwzid

2

、しかし...

ParameterExpression paramExp = Expression.Parameter(t, "p"); // the parameter: p 

MemberExpression memberExp = 
    Expression.MakeMemberAccess(paramExp, t.GetMember(propertyName).FirstOrDefault()); 

は次のようになります。

ParameterExpression paramExp = Expression.Parameter(t, "p"); // the parameter: p 

MemberExpression otherEntityExp = 
    Expression.MakeMemberAccess(paramExp, t.GetMember("anotherentity").FirstOrDefault()); 

MemberExpression memberExp = 
    Expression.MakeMemberAccess(otherEntityExp, t.GetMember(propertyName).FirstOrDefault()); 
関連する問題