2010-06-11 94 views
4

我是一個初學者,最終開始瞭解匿名類型。元組對比匿名類型與Expando對象。 (關於LINQ查詢)

(見舊後What is the return type for a anonymous linq query select? What is the best way to send this data back?)所以在LINQ

查詢您構成LINQ查詢權在你想返回值的類型?看來這樣做的方式是匿名類型的權利?

有人可以向我解釋是否以及何時可以使用Tuple/Expando對象嗎?他們都似乎很simliar?

回答

3

你沒有說明你的問題的上下文,所以我會回答LinqToObjects和LinqToSql。

在LinqToObjects中,假設您有一個List<Customer> source

//Straight projection. 
    //no new instances are created when query is evaluated. 
IEnumerable<Customer> result = 
    from c in source where c.Name == "Bob" 
    select c; 

    //Different Type projection 
    //a new instance of CustomerName is created 
    // for each element in the result when the query is evaluated. 
IEnumerable<CustomerName> result = 
    from c in source where c.Name == "Bob" 
    select new CustomerName() {Name = c.Name}; 

    //Anonymous Type Projection  
    //a new instance of an anonymous type is created 
    // for each element in the result when the query is evaluated. 
    //You don't have access to the type's name 
    // since the compiler names the type, 
    // so you must use var to talk about the type of the result. 
var result = 
    from c in source where c.Name == "Bob" 
    select new {Name = "Bob"}; 

    //Tuple Projection (same as Different Type Projection) 
    //a new instance of Tuple is created 
    // for each element in the result when the query is evaluated. 
IEnumerable<Tuple<string, int>> result = 
    from c in source where c.Name == "Bob" 
    select new Tuple<string, int>(){First = c.Name, Second = c.Id}; 

在LinqToSql,假設你有一個IQueryable<Customer> db.Customers

//Straight projection 
    //when the query is resolved 
    // DataContext.Translate<Customer> is called 
    // which converts the private dbReader into new Customer instances. 
IQueryable<Customer> result = 
    from c in db.Customers where c.Name == "Bob" 
    select c; 

    //Different Type Projection 
    //when the query is resolved 
    // DataContext.Translate<CustomerName> is called 
    // which converts the private dbReader into new CustomerName instances. 
    // 0 Customer instances are created. 
IQueryable<Customer> result = 
    from c in db.Customers where c.Name == "Bob" 
    select new CustomerName() {Name = c.Name}; 

    //Different Type Projection with a twist 
    //when the query is resolved 
    // DataContext.Translate<CustomerGroup> is called 
    // which converts the private dbReader into new CustomerGroup instances. 
    // 0 Customer instances are created. 
    //the anonymous type is used in the query translation 
    // yet no instances of the anonymous type are created. 
IQueryable<Customer> result = 
    from c in db.Customers 
    group c by new {c.Name, TheCount = c.Orders.Count()} into g 
    select new CustomerGroup() 
    { 
    Name = g.Key.Name, 
    OrderCount = g.Key.TheCount, 
    NumberInGroup = g.Count() 
    }; 

好吧,那現在夠了。

+0

我使用linq2entities,所以我覺得它就像你的第一個例子。 對匿名使用元組有什麼原因或好處? – punkouter 2010-06-13 16:00:43

+0

匿名類型的實例不會很好地跨越方法邊界。元組沒有這個問題。 – 2010-06-13 16:46:50

+0

但基本情況下,在快速linq查詢中發回一個對象而無需定義一個新類,我猜這就是anon類型的全部要點。 – punkouter 2010-06-14 15:08:57

4

元組和擴展對象通常不在LINQ中使用。它們與匿名類型完全不同。

匿名類型通常用於「塑造」LINQ查詢;例如,您可以定義一個具有string Name屬性和int Age屬性的類型。

元組是僅充當「對」或「三元」類結構的類型。例如,可以定義Tuple<string, int>,但屬性的名稱分別命名爲Item1Item2,而不是NameAge。元組通常不用於形成LINQ查詢,因爲這些屬性名稱使得代碼不太清晰。

ExpandoObject是完全不同的。它允許您在運行時將屬性添加到現有對象。

+0

好吧,幫助感謝。什麼是元組優於匿名的優勢?我猜它與你有什麼關係,不能在方法外使用匿名類型?或者其他的東西? Expandoobject對我來說似乎與linq查詢無關的動態類型有關...也許,如果我得到客戶的linq查詢,我想給客戶類添加一個'rating'整數爲Expando /動態?這是使用它的原因嗎? – punkouter 2010-06-13 15:55:10

+0

確實可以在任何地方使用元組,而匿名類型僅限於該方法。但是,更常見的是用有意義的字段名稱來定義自己的結果類型。 ExpandoObject是一種動態對象;雖然它可以在LINQ查詢中使用(就像Tuple類型一樣),但通常不會。要在LINQ查詢中添加字段,定義新的匿名類型比使用ExpandoObject更常見。也就是說,EO是相當新的,所以隨着時間的推移,這可能成爲一種更受歡迎的方法。 – 2010-06-13 17:20:44

+0

好..只是想知道如果我可以找到任何藉口使用新的4.0的東西呢.. – punkouter 2010-06-14 15:09:58