我已經建立了一個代表類別樹,以幫助進行分類一些我們所儲存的數據的數據庫結構的所有後代項目。實現方式是Category
表中的每條記錄都有一個可爲空的外鍵,返回到Category
表中,以表示此類別(一對多)的父Category
,基本上允許更廣泛的父級別中的子類別。有一個CategoryMembership
表,它將Item
表中的記錄鏈接到其各自的Category
(多對多)。我創建該數據庫的DBML,它具有包括以下成員訪問結構:
Dim aCategory As New Category()
Dim aParentCategory As Category = aCategory.Parent
Dim aChildCategoryCollection As EntitySet(Of Category) = aCategory.Subcategories
Dim aMembershipCollection As EntitySet(Of CategoryMembership) = aCategory.CategoryMemberships
在aMembershipCollection
每一個項目都有以下成員訪問結構:
Dim aMembership As CategoryMembership = aMembershipCollection.First()
Dim aLinkedCategory As Category = aMembership.Category
Dim aLinkedItem As Item = aMembership.Item
的要求
我正在嘗試構建一個LINQ表達式,該表達式允許我確定哪個Items
具有CategoryMemberships
用於請求的Category
(即aCategory.id = myID
)或所請求的Category
的後代的成員身份,這個想法是我希望所有Items
位於父類別或其多個子類別級別中。
本質上查詢將建在類似的方式:
Dim results As IQueryable(Of Item) = _
From cm In db.CategoryMemberships.Where(myInCategoryPredicate(myID)) _
Select cm.Item
...其中myInCategoryPredicate
返回LINQ表達的對象,這將有助於我作出這樣的決定。這當然是基於假設CategoryMembership
表是開始檢索IQueryable(Of Item)
的地方。我可能在這裏做了一個錯誤的假設,這就是我尋求建議的原因。
的問題
我有一個很難只見樹木不見森林。我無法確定是應該從Category還是從CategoryMembership開始構建謂詞,也不能確定能夠實現我想要的內容的必需代碼。我希望已經爲數據庫構建了類似樹結構的其他人可能能夠幫助我導航DBML類。
可用資源
我以前發了過去使用的PredicateBuilder和我比較熟悉它的工作原理,但我一直沒能想出一個辦法,通過樹向上遍歷,並建立一個謂語遞歸地表明項目是否在所請求的類別或其子類別中。到目前爲止,我已經產生了以下,具有非常明顯的差距標記SomeRecursiveCall():
Private Function InCategory(ByVal myID As Integer) As Expression(Of Func(Of CategoryMembership, Boolean))
Dim predicate = PredicateBuilder.False(Of CategoryMembership)()
predicate = predicate.Or(Function(cm) cm.fkCategoryID = myID OrElse SomeRecursiveCall())
Return predicate
End Function
不過,我認識到,一個謂詞建設者可能是沒有用的,在這裏和任何可能需要不同的方向。
我認爲總會有選擇Category
紀錄被請求的ID,並從中建立ID的列表和Subcategories
所有成員遞歸然後使用該名單,以評估對一。載有()比較的可能性名單,但我想知道是否沒有其他選項不那麼難受。
我討厭聽到「你不能這樣做」,但我理解你的意思。這是一個失望,我不能只是禁用延遲執行,以便允許數據限制。不幸的是,編程解決方案爲我最終確定的.Any()重載引發了一個不支持的異常,這會導致我想要的行爲(如您所示)。感謝您指點我CTE。一旦完成,我將發佈存儲過程的結果。 – lsuarez 2011-03-08 05:56:44