如何实现递归自联接实体框架?

时间:2015-05-18 07:51:16

标签: c# .net sql-server entity-framework

我在数据库中有菜单表,它有自引用外键即ParentID。 Bellow是我的菜单类(DB First Approach)

public partial class Menu
{
    public Menu()
    {
        this.Menu1 = new HashSet<Menu>();
        this.Products = new HashSet<Product>();
    }

    public int MenuID { get; set; }
    public string Name { get; set; }
    public Nullable<int> ParentID { get; set; }
    public virtual ICollection<Menu> Menu1 { get; set; }
    public virtual Menu Menu2 { get; set; }
    public virtual ICollection<Product> Products { get; set; }
}

我想实现以下内容,

  1. 我希望整个层次结构使用菜单ID,例如“如果我通过7,那么结果应该是菜单ID 7的所有子和子子”
  2. 如果我通过7,那么我想要菜单ID为7的所有父母和超级父母。
  3. 在发布此问题之前,我在StackOverflow上发现了几篇文章,但他们要求实施Code First Approach。以下是在Entity Framework Self Join Most efficient method of self referencing tree using Entity Framework

    之前在Stackoverflow上发布的问题

1 个答案:

答案 0 :(得分:3)

我不确定你是否意识到这一点,但Menu1是你的父菜单,而Menu2是你的孩子菜单。 (我建议将Menu1和Menu2属性重命名为父级和子级)。

我相信您链接的所有解决方案都有可用于解决问题的解决方案。

代码示例:

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);
        }
    }
}

这样的事情可以帮助你获得一个名为current的Menu实例的所有父母和所有孩子。注意效率很糟糕。但这是一个不同的问题。在我的性能测试表明我的应用程序存在瓶颈之前,我不会优化代码。

有趣的引用:&#34;过早的优化是所有邪恶的根源。&#34; - Donald Knuth