2011-08-26 53 views
2

如何獲取參與linq表達式的所有類型?我其實需要這樣才能緩存查詢結果。Linq - 如何獲取參與表達的類型

在這個例子中很容易:

var Query = (from x in DataContext.Current.ContractDurations select x); 

爲 我需要的那種類型的

Query.ElementType 

提供,但我這樣做的時候會發生什麼:

var Query = (from x in DataContext.Current.ContractDurations select x.ID); 

的ElementType將是int。同樣的問題將存在於連接中,其中ElementType將是一些隨機的匿名類型。

+0

嗨不完全理解你的意思。你想要第二條語句返回什麼結果 – Pintac

+0

你是說你想在這兩種情況下得到x的類型嗎?如果是這樣,我認爲你將需要'走表達樹'(在谷歌搜索 –

+0

)你想要獲取查詢元素類型,或查詢中涉及的所有類型?從你的問題中不太清楚 –

回答

0
public class QueryExpressionVisitor : ExpressionVisitor 
{ 
    public List<Type> Types 
    { 
     get; 
     private set; 
    } 


    public QueryExpressionVisitor() 
    { 
     Types = new List<Type>(); 

    } 
    public override Expression Visit(Expression node) 
    { 
     return base.Visit(node); 
    } 

    protected override Expression VisitConstant(ConstantExpression node) 
    { 
     if (node.Type.IsGenericTypeDefinition && node.Type.GetGenericTypeDefinition() == typeof(IQueryable<>)) 
      CheckType(node.Type.GetGenericArguments()[0]); 
     return base.VisitConstant(node); 
    } 

    protected override Expression VisitMember(MemberExpression node) 
    { 
     CheckType(node.Member.DeclaringType); 
     return base.VisitMember(node); 
    } 



    private void CheckType(Type t) 
    { 
     if (!Types.Contains(t)) 
     { 
      Types.Add(t); 
     } 
    } 
} 
0

我在這裏沒有看到問題...只要原始數據上下文是IQueryable,您應該可以訪問ElementType。

請參閱以下內容:

void Main() 
{ 
    List<Alerts> alerts = new List<Alerts>(); 
    alerts.Add(new Alerts(DateTime.Now.AddDays(-1))); 
    alerts.Add(new Alerts(DateTime.Now)); 

    IQueryable<Alerts> qAlerts = alerts.AsQueryable(); 

    var query1 = qAlerts.Select (a => a.Begins); 
    Console.WriteLine(query1.ElementType); 

    var query2 = qAlerts.Select (a => a); 
    Console.WriteLine(query2.ElementType); 

    var query3 = alerts.Select (a => a); 
    Console.WriteLine(query3.AsQueryable().ElementType); 
} 
public class Alerts 
{ 
    public DateTime Begins {get; set;} 
    public Alerts(DateTime begins) 
    { 
     Begins = begins; 
    } 
} 

的關鍵是的ElementType是IQueryable的成員,所以你需要確保無論是原始來源是IQueryable的(如在QUERY1和QUERY2),或者你將查詢轉換爲IQueryable(如query3)。

最後,對於這種事情,抓住LinqPad的副本...免費版本是偉大的,付費版本會給你intellisense。

+0

我想我沒有通過這裏。可能還沒有正確解釋這一點。 'ElementType'的問題是它指向IQueriable的返回類型。所以例如,如果一個查詢有一堆連接,並最終選擇一個int,我會在ElementType中得到Int32,這不是我想要的。我想要的是知道** all **參與查詢的類型,然後我可以過濾掉其中哪些是數據對象(實體),以便能夠在這些類型上添加緩存依賴關係。 – John