我已閱讀以下內容:https : //stackoverflow.com/a/20766203/10046099
我不明白的是這部分:
創建運算式樹是為了將諸如查詢運算式之類的代碼轉換為可以傳遞給其他行程并在那里執行的字串的任務。就是這么簡單。
如果我們得到查詢運算式,為什么不能直接將其轉換為發送到 sql 資料庫的 sql 字串?為什么需要樹?因為發生的事情不是直接將查詢運算式轉換為 sql 字串,而是先將其轉換為樹,然后將樹轉換為 sql 字串,這意味著 2 步而不是 1 步。
我很感激最簡單的解釋。
更新
我們看下面的linq
IEnumerable<int> scoreQuery =
from score in scores
where score > 80
select score;
你能把它變成運算式樹作為二叉樹圖嗎?也許在此之后,我會更容易將運算式樹轉換為 sql 字串。
uj5u.com熱心網友回復:
如果我們有查詢運算式,為什么不能直接轉換成sql字串
你會使用什么 SQL 方言?這意味著 LINQ 系統基本上必須包含所有可能的 SQL 方言生成器。
此外,您將無法在多個步驟中生成運算式樹。是的,這是一件事 - 生成第一個 where,然后在長長的 if 條件串列中添加 where 子句。
通過生成運算式樹,您不僅可以在生成 SQL 之前對其進行操作,還可以通過配接器進一步完成 SQL 生成。這樣您就可以支持每種 SQL 方言。
uj5u.com熱心網友回復:
編譯器將您的代碼轉換為
IEnumerable<int> scoreQuery scores.Where(score => score > 80).Select(score => score);
第二步,將這段代碼轉化為
ParameterExpression parameterExpression = Expression.Parameter(typeof(int), "score");
BinaryExpression body = Expression.GreaterThan(parameterExpression, Expression.Constant(80, typeof(int)));
ParameterExpression[] array = new ParameterExpression[1];
array[0] = parameterExpression;
Expression<Func<int, bool>> whereExpression = Expression.Lambda<Func<int, bool>>(body, array);
parameterExpression = Expression.Parameter(typeof(int), "score");
ParameterExpression body2 = parameterExpression;
ParameterExpression[] array2 = new ParameterExpression[1];
array2[0] = parameterExpression;
Expression<Func<int, int>> selectExpression = Expression.Lambda<Func<int, int>>(body2, array2);
IEnumerable<int> scoreQuery scores.Where(whereExpression).Select(selectExpression);
這是如何存盤例如應該檢查分數是否大于80的資訊的方式。基本上,您可以像上面那樣直接撰寫代碼,但它更費力且更難閱讀,這就是編譯器提供上述單行代碼的縮寫的原因。
在運行時,Entity Framework 或任何其他 ORM 工具將分析上面的運算式樹。它將使用存盤在那里的資訊來構建 SQL 查詢。例如,因為NodeTypewhere 運算式的 是ExpresionType.GreaterThan,EF 將>在 SQL 查詢中使用 a 。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/349949.html
