如何在实体框架中实现递归自连接?

9 浏览
0 Comments

如何在实体框架中实现递归自连接?

我在数据库中有一个菜单表,其中有一个自引用外键ParentID。以下是我的Menu类(DB First方法):

public partial class Menu
{
    public Menu()
    {
        this.Menu1 = new HashSet();
        this.Products = new HashSet();
    }
    public int MenuID { get; set; }
    public string Name { get; set; }
    public Nullable ParentID { get; set; }
    public virtual ICollection Menu1 { get; set; }
    public virtual Menu Menu2 { get; set; }
    public virtual ICollection Products { get; set; }
}

我想要实现以下功能:

  1. 我希望使用菜单ID获取整个层次结构,例如“如果我传递7,则结果应该是菜单ID为7的所有子级和子子级”
  2. 如果我传递7,则我希望获取菜单ID为7的所有父级和超级父级。

在发布这个问题之前,我在StackOverflow上找到了几篇文章,但它们要求实现Code First方法。以下是在Stackoverflow上发布的问题:Entity Framework自连接使用Entity Framework实现自引用树的最有效方法

0
0 Comments

问题的原因是,用户想要在Entity Framework中实现递归自连接。用户想要获取一个Menu实例的所有父级和子级。

解决方法是,用户可以使用以下代码来获取当前Menu实例的所有父级和子级:

void GetParents(Menu current) {
    dbContext.Entry(current).Reference(m => m.Menu2).Load();
    while (current.Menu2 != null) {
        current = current.Menu2; 
        dbContext.Entry(current).Reference(m => m.Menu2).Load();
    }
}
void GetChildren(Menu current) {
    if (current == null) {
        return;
    } else {
        dbContext.Entry(current).Collection(m => m.Menu1).Load();
        foreach (var menu in m.Menu1) {
            GetChildren(menu);
        }
    }
}

这段代码可以获取当前Menu实例的所有父级和子级。注意,这段代码的效率很低,但是这是一个不同的问题。用户可以在性能测试中找到应用程序的瓶颈后再对代码进行优化。

用户还可以使用以下代码来获取所有级别的父级和子级:

List GetChildren(Menu current) {
    List children = new List();
    dbContext.Entry(current).Collection(m => m.Menu1).Load();
    foreach (var menu in current.Menu1) {
        children.Add(menu);
        children.AddRange(GetChildren(menu));
    }
    return children;
}

这段代码可以获取当前Menu实例的所有父级和子级,包括多个级别。

最后,用户还可以使用以下代码来标记答案为正确答案:

if (currentMenu != null) {
    dbContext.Entry(currentMenu).State = EntityState.Modified;
    dbContext.SaveChanges();
}

点击回答下方的"标记为正确答案"按钮即可将答案标记为正确答案。

通过以上解决方法,用户可以实现在Entity Framework中进行递归自连接。

0