LINQ 表示式樹 Expression

2021-08-30 05:53:49 字數 3572 閱讀 9581

在 linq to objects 中,擴充套件方法需要將乙個委託型別作為引數,這樣就可以將λ表示式賦予引數。

λ達式也可以賦予expression型別的引數。expression型別指定,來自於λ表示式的表示式樹儲存在程式集中。

這樣,就可以在執行期間分析表示式,並進行優化,以便於查詢資料來源。

下面看看乙個前面使用的查詢表示式:

var brazilracers = from r in racers

where r.country == "brazil"

orderby r.wins

select r;

這個查詢表示式使用了擴充套件方法where、orderby 和select。

enumerable 類定義了where 擴充套件方法,並將委託型別func作為引數謂詞。

public static ienumerablewhere(this ienumerablesource, funcpredicate);

這樣,就把λ表示式賦予謂詞。這裡λ 表示式類似於前面介紹的匿名方法。

funcpredicate = r.country == "brazil";

enumerable 類不是唯一定義了擴充套件方法where 的類。

queryable類也定義了where擴充套件方法。

這個類對where 擴充套件方法的定義是不同的:

public static iqueryablewhere(this iqueryablesource,

expression> predicate);

其中,λ 表示式賦予型別expression,它的操作是不同的:

expression> predicate = r.country == "brazil";

除了使用委託之外,編譯器還會把表示式樹放在程式集中。表示式樹可以在執行期間讀取。

表示式樹從派生自抽象基類expression 的類中建立。

expression 類與expression不同。

繼承了expression 的表示式類有binaryexpression、constantexpression、invocationexpression、lambdaexpression 、

newexpression 、newarrayexpression 、ternaryexpression 、unaryexpression 等。編譯器會從λ 表示式中建立表示式樹。

例如,λ表示式r.country==「brazil」使用了parameterexpression、memberexpression、constantexpression

和methodcallexpression,來建立乙個表示式樹,將該樹儲存在程式集中。之後在執行期間使用這個樹,建立乙個用於底層資料來源的優化查詢。

private static void displaytree(int indent, string message, expression expression)

! nodetype: ; expr: ", "".padleft(indent, '>'), message, expression.nodetype, expression);

indent++;

switch (expression.nodetype)

displaytree(indent, "body", lambdaexpr.body);

break;

case

expressiontype.constant:

constantexpression constexpr = (constantexpression)expression;

console.writeline(" const value: ", output, constexpr.value);

break;

case

expressiontype.parameter:

parameterexpression paramexpr = (parameterexpression)expression;

console.writeline(" param type: ", output, paramexpr.type.name);

break;

case

expressiontype.equal:

case

expressiontype.andalso:

case

expressiontype.greaterthan:

binaryexpression binexpr = (binaryexpression)expression;

if (binexpr.method != null)

console.writeline(" method: ", output, binexpr.method.name);

else

console.writeline(output);

displaytree(indent, "left", binexpr.left);

displaytree(indent, "right", binexpr.right);

break;

case

expressiontype.memberaccess:

memberexpression memberexpr = (memberexpression)expression;

console.writeline(" member name: , type: ", output, memberexpr.member.name, memberexpr.type.name);

displaytree(indent, "member expr", memberexpr.expression);

break;

default:

console.writeline();

console.writeline(".... ", expression.nodetype, expression.type.name);

break;}}

前面已經介紹了用於顯示表示式樹的表示式。

這是乙個λ表示式,它使用乙個racer 引數,表示式體提取贏得比賽次數超過6 次的巴西賽手:

private static void expressions()

下面看看結果。λ表示式包含乙個parameter 和乙個andalso 節點型別。

andalso 節點型別的左邊是乙個equal 節點型別,

右邊是乙個greaterthan 節點型別。

equal 節點型別的左邊是memberaccess 節點型別,

右邊是constant 節點型別。

使用型別expression的乙個例子是linq to sql。

linq to sql 用expression引數定義了擴充套件方法。

這樣,訪問資料庫的linq 提供程式就可以讀取表示式,建立乙個執行期間優化的查詢,從資料庫中獲取數

據。

LINQ 表示式樹 Expression

在 linq to objects 中,擴充套件方法需要將乙個委託型別作為引數,這樣就可以將 表示式賦予引數。達式也可以賦予expression型別的引數。expression型別指定,來自於 表示式的表示式樹儲存在程式集中。這樣,就可以在執行期間分析表示式,並進行優化,以便於查詢資料來源。下面看看...

linq表示式對比lambda表示式

什麼是linq表示式?什麼是lambda表示式?前一段時間用到這個只是,在網上也沒找到比較簡單明瞭的方法,今天就整理了一下相關知識,有空了再仔細研究研究 public program ling表示式 var stus1 from s in allstudent where s.name 王二 sel...

初識Linq表示式

由於近期做專案涉及到linq表示式,正好來學習一下。linq languageintegrated query 語言整合查詢,是一組用於 c 和visual basic語言的擴充套件。它允許編寫c 或者 visual basic 以查詢資料庫相同的方式操作記憶體資料。約束linq查詢表示式必須以fr...