gpt4 book ai didi

vb.net - 构建 LINQ 表达式以查找与树节点的所有后代相关的项目

转载 作者:行者123 更新时间:2023-12-02 06:57:08 25 4
gpt4 key购买 nike

场景

我构建了一个表示类别树的数据库结构,以帮助对我们存储的一些数据进行分类。具体实现是,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 具有适用于所请求的 CategoryCategoryMemberships(即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

但是,我意识到谓词构建器在这里可能没有任何用处,并且可能需要不同的方向。

我认为总是有可能为请求的 ID 选择 Category 记录,并从中递归地构建 ID 列表以及 Subcategories 的所有成员使用该列表来评估该列表上的 .Contains() 比较,但我想知道是否没有其他选项不太让人感觉那么丑陋。

最佳答案

您无法在 linq to sql 查询中执行数据限制递归(您希望递归直到没有更多数据可供获取)。这是因为查询翻译器需要知道何时停止生成查询,并且它无法查看数据来知道这一点。

您可以使用 Common Table Expression在 TSql 中执行数据限制递归...如果您只是将该 CTE 放入 View 中,则可以从 linq 到 sql 查询该 View 。

关于vb.net - 构建 LINQ 表达式以查找与树节点的所有后代相关的项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5225568/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com