2015-04-21 39 views
4

實體框架,我們可以這樣做:LINQ to SQL如何知道委託內部是什麼?

MyContext context = ... // a normal EF context 

var products = context.Products.Where(p => p.Location == "France") ; 

var products = context.Products.Where(p => p.CategoryId == 54) ; 

這是在其相應的SQL查詢的同時平移。

OK,但地方在那裏,有這麼處理這一段代碼:

public static IEnumerable<T> Where(Func<bool, T> func) { 
    ...... 
} 

從這個Where功能,如何LINQ to SQL識貨的func執行?

也許很明顯的答案,但我真的找不到它。

回答

6

你真的應該在你的代碼上做一個轉到定義。使用LINQ到SQL和實體框架的function

IQueryable<TSource> Where<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate) 

包含在使用expression treesSystem.Linq.Queryable,是能夠「描繪」的代碼段一constuct。小報價:

表達式樹表示代碼在類似樹的數據結構,其中每個節點是一個表達,例如,一個方法調用或二進制操作例如x <年。

例如,你的第一個表達

var products = context.Products.Where(p => p.Location == "France"); 

是由C#編譯器轉換爲這樣的代碼:

ParameterExpression par = Expression.Parameter(typeof(Product), "p"); 
LambdaExpression lambda = Expression.Lambda(
    Expression.Equal(
     Expression.Property(par, "Location"), 
     Expression.Constant("France")), 
    par); 

var products = context.Products.Where(lambda); 

現在......而一個表達式樹的創建非常簡單,反向操作(去構建表達式樹並創建查詢)是非常非常複雜的事情。大頭痛複雜。近乎神奇的複合體:-)

問題不在於構建表達式樹。這很容易。你使用ExpressionVisitor,你就完成了。問題在於合併LINQ查詢的各個層次並理解程序員想要獲得什麼。

我會補充一點,IL(.NET的「彙編」)足夠高,可以反編譯它(參見例如IlSpy)。至少有一個庫,DelegateDecompiler能夠將委託編譯到表達式樹中,所以即使沒有表達式樹,LINQ到SQL和EF也可以直接使用類似和反編譯的方法到SQL語言。

相關問題