2017-06-01 239 views
0

我想從列表中的對象列表中選擇一個列表中的對象,該對象列表中包含基於對象列表中的屬性的列表中的另一個類型的對象。LINQ基於對象內列表中的屬性選擇對象

例如

class TypeA{ 
    string Name {get; set;} 
    List<TypeB> ListOfTypeB {get; set;} 
} 

class TypeB{ 
    int Age {get; set;} 
    bool Active {get; set;} 
} 

我有一個由數據庫填充類型列表的,我要查詢類型A的列表,並返回類型A的基礎上的TypeB活動屬性,它是一個列表TypeA對象內的列表。

任何幫助將是偉大的。

謝謝

回答

1

您寫道:

我要查詢類型A的列表,並返回類型A的基礎上 的TypeB中的Active屬性列表。

該規範有點不清楚。我假定你的意思是你想讓至少有一個TypeA對象的真實值爲TypeB.Activity(或那些帶有錯誤值的對象)。

答案取決於您是要執行您的查詢爲Enumerable還是Queryable。換句話說:您是否首先想要將對象存入本地內存,然後執行查詢(AsEnumerable),或者是否希望讓數據庫執行查詢(Asqueryable),然後僅將有效結果返回到本地內存。

AsEnumerable

這種方法不是很有效,因爲這將意味着你處理之前獲得完整的類型A和類型B表到本地內存。

但是您的查詢就會很簡單:

var AwithActivity = allTypeA 
    .Where(a => a.ListOfTypeB.Any(b => b.Activity)); 

在口頭上:

typeA元素的完整序列,只需要具有至少一個ListOfTypeB元素與真值的typeA元素物業Activity

AsQueryable已

如果你的數據庫設置正確,你將有兩個表。一張桌子TypeA項目和一個桌子TypeB項目。

TypeATypeB有一對多的關係。每個TypeA有零個或多個TypeB,每個TypeB都屬於一個TypeA

在你的數據庫中,TypeATypeB都有一個主鍵。每個TypeB將擁有一個到它所屬的TypeA的外鍵。

這是相當標準的數據庫。它可以幫助您查詢。利用這些定義您的查詢將被翻譯成:

我希望所有類型A的對象,其中有是有一個外鍵此類型A對象和活動的真實值的至少一個的TypeB對象

查詢將是:

var results = TypeATable   // groupjoin table TypeA with table TypeB 
    .GroupJoin(TypeBTable, 
     typeA => typeA.PrimaryKey, // from every typeA use the primary key 
     typeB => typeB.ForeignKey, // from every typeB use the foreign key to the TypeA 
     (a, allB) => new    // for every A with all matching typeB: 
     {        // create a new anonymous type 
     A = a,      // with the found A 
     HasActivity = allB   // and a boolean that says if there was 
      .Any(b => b.Activity), // at least one B with a true Activity 
     }); 

要獲得所有類型A與至少一個活動:

var AWithActivity = results.Where(result => result.HasActivity) 
    .Select(result => result.A); 

要獲得任何活動都所有類型A:

var AwithoutActivity = result.Where(result => !result.HasActivity) 
    .Select(result => result.A); 

加成 如果可能是一個的typeA和TYPEB之間的關係是不是一個對許多,但許多一對多。在這種情況下,您將所有活動的typeB對象和外鍵找到的所有typeA對象添加到此活動的typeB對象中

+0

您好,您的正確,我重新閱讀我的回覆,並且它有點含糊,我的模式和關係很好結構像你所描述的那樣。我一直在想的是嵌套選擇查詢的可能性。感謝您的詳細解答讓我看到了我的禮儀。 – Csharper

1

它實際上將取決於您如何實現過濾器邏輯。如果你想找到類型A的列表,其類型B至少包含一個活動標誌,那麼你可以像下面這樣做。

listOfTypeA.Where(a => a.ListOfTypeB.Any(b => b.Active)).ToList(); 
相關問題