gpt4 book ai didi

c# - 执行延迟查询以识别所有后代?

转载 作者:行者123 更新时间:2023-11-30 23:30:01 25 4
gpt4 key购买 nike

所以我有一个看起来像这样的简单表格来表示支持动态 N 级深度的类别和子类别树。

CategoryID int NOT NULL (PK)
ParentCategoryID int NULLABLE (FK to self)
CategoryName varchar(100) NOT NULL

我的实体(凭内存输入,如果这里有愚蠢的错误,请见谅):

public class Category
{
public int CategoryId { get; set; }
public int ParentCategoryId { get; set; }
public string CategoryName { get; set; }

public virtual Category ParentCategory { get; set; }
public IDbSet<Category> ImmediateChildCategories { get; set; }
}

在 C# (4.5+) 的 Entity Framework (6.x) 中使用延迟执行的 lambda 表达式,我如何识别属于指定类别的所有类别?

我想要的伪代码 SQL 查询是这样的:

SELECT * FROM Category WHERE AnyLevelOfAncestorId = 123;

我希望看到的伪代码 EF 查询是这样的(那里有分页以强调我对执行延迟支持的需求):

_db.Categories.Where(cat => cat.HasAncestor(123)).Skip(1000).Take(25).ToList();

其他详细信息:

  • 具有 NULL ParentCategoryID 的类别是树的根节点(可以有多个)。
  • 任何类别都不会拥有自己的 CategoryID 或任何后代 ID 作为 ParentCategoryID(即没有循环关系并且所有关系最终终止于根节点,尽管我可能会查询低于根节点的 ID )
  • 我不确定是否要在结果中包含指定的 ID (123)。因此,我会接受任何一种答案,并在我知道是否还想包括那个特定答案后根据需要进行调整。

最佳答案

我假设您的 Category 实体类型有一个集合导航属性,用于检索其子类别(通过外键关联)。此导航属性会导致子类别在第一次访问时延迟加载。您可以定义一个方法,在根及其子项上递归调用此导航属性(例如 ChildCategories)。

public static IEnumerable<Category> GetDescendants(Category root)
{
return root.ChildCategories.Concat(root.ChildCategories.SelectMany(GetDescendants));
}

上述代码的缺点是它会发出一个单独的数据库查询来检索每个 parent 的 child 。我不认为 Entity Framework 目前支持生成单个递归查询(EF 6.1.3)。相反,我建议您在数据库中定义一个递归 View ,用于投影所有类别-后代对;将此 View 作为实体包含在您的实体数据模型中;然后从您的 LINQ 查询查询或加入它。可以使用特定于 DBMS 的技术来定义 View 。 SQL Server 支持 recursive CTEs , 和 recent versions of Oracle 一样.

关于c# - 执行延迟查询以识别所有后代?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35090171/

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