2013-04-29 85 views
2

我已經建立了以下LINQ查詢LINQ'select new'做什麼?

var activeMembers = from m in context.py3_membershipSet 
        join c in context.ContactSet on m.py3_Member.Id equals c.ContactId 
        where m.statuscode.Value == 1 
        orderby m.py3_name 
        select m; 

但因爲我已經看到格式化爲這樣一個例子:

var contacts = 
(
    from c in xrm.ContactSet 
    join a in xrm.AccountSet on c.ParentCustomerId.Id equals a.Id 
    where a.Name == "Acme Pty Ltd" 
    select new 
    { 
     Name = c.FullName, 
     DOB = c.BirthDate, 
     Gender = (c.FormattedValues.Contains("gendercode") ? c.FormattedValues["gendercode"] : "Ambiguous") 
    } 
); 

(我意識到這是一組不同的數據)什麼的在這種情況下包含'選擇新'實際上是做什麼的?

它比第一個代碼塊中的示例有什麼好處?

我意識到有些人可能會發現這是一個乏味的問題,但我想學習LINQ並需要快速學習它。但我也不想運行一些東西 - 我不完全瞭解 - 在客戶端上運行CRM

回答

4

由於以前的答案已經注意到兩種方法都返回一個匿名類型。但要完全回答你的問題:「第一個聲明比第一個聲明有什麼好處?」

第一條語句原樣返回所有m的字段。如果你有7個「列」,那麼activeMembers將包含所有這些和他們包含的任何數據。

在第二個語句中,您將結果投影到只包含3個字段的自定義匿名對象中。不僅如此,在將代碼存儲到匿名對象之前,您還可以在「源代碼字段」上執行邏輯。這給你很大的靈活性,將它們存儲在一個容器類中,而你實際上不必在代碼中定義該類。

你也可以做select new SomeClass { }這會將你的結果投影到預定義的類容器中。

下面的僞代碼可以或可以不理解的差異會有所幫助:

var myQuery = from p in someContext.someTable 
       group p by p.someField into g 
       select new MyContainer { 
        Field1 = g.Sum(a => a.field1) 
        Field2 = g.Max(a => a.field2) 
       }; 

myQuery在上述現在的MyContainer的集合。如果我省略了類MyContainer,那麼它將是包含我指定的字段的匿名類型的集合。顯然,這裏的區別在於MyContainer必須在代碼中的其他地方定義,而匿名類是在編譯時爲您構建/定義的。在:

var myQuery = from p in someContext.someTable 
       select p; 

myQuery是包含在someTable所有字段和它們的值的一個匿名類。

+0

因此,基本上,第二個查詢將結果限制爲已知名稱的已定義組,而不是未定義的一組x字段(如第一個)? – 2013-04-29 20:24:10

+1

是的,沒有。第一組中的x字段仍然是「已知的」(至少是編譯器)。你可以在IDE中看到這個,輸入'activeMembers.FirstOrDefault()。',可用的字段就會彈出。第二種選擇只是讓您更多地控制進入匿名類型的內容,字段的名稱,並允許您在字段上執行計算。 – Kittoes0124 2013-04-29 20:45:01

+0

非常徹底。爲你+1好,先生。 – 2013-04-30 06:06:11

5

LINQ返回匿名對象的集合,無論哪種方式。讓我們定義該對象的佈局以及哪個屬性/屬性名稱包含在該匿名對象中。

您也可以使用select new ClassName { }返回您定義的實體類的實例列表。

+2

Linq返回一個集合,而不是一個匿名對象,除非您使用像Single或First或Count這樣的操作符之一。匿名類型指定該集合中每個元素的公共成員。 – 2013-04-29 20:14:25

+0

謝謝羅伯特,很好的電話。我更新了我的帖子。 – 2013-04-29 20:16:00

1

您正在使用Queryable.Select<TSource, TResult>(IQueryable<TSource>, Expression<Func<TSource, TResult>>)方法,其中ContactSet是TSource,而匿名對象返回類型是TResult。您的代碼也可寫爲

...Select(r => new { 
         Name = c.FullName, 
         DOB = c.BirthDate, 
         Gender = (c.FormattedValues.Contains("gendercode") ? c.FormattedValues["gendercode"] : "Ambiguous") 
        }) 

其中select方法正在返回匿名類型的集合。

此外,還有一點在引擎蓋下,因爲它看起來像你在查詢數據庫。您的IQueryable實現將查看您編寫的Select方法,並將您提供的表達式轉換爲有效的SQL,以便它可以檢索您要返回的匿名對象的所有必需信息。請注意,我說你的IQuerable的實現將提供的表達式(不是函數)翻譯成sql。 Select擴展方法只接受表達式,而不是函數,因爲它不能將函數轉換爲sql。