如何实现递归自连接实体框架?
Posted
技术标签:
【中文标题】如何实现递归自连接实体框架?【英文标题】:How to implement recursive self join entity framework? 【发布时间】:2015-05-18 07:51:16 【问题描述】:我在数据库中有菜单表,它具有自引用外键,即 ParentID。下面是我的菜单类(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;
我想实现以下的东西,
-
我想要使用菜单 id 的整个层次结构,例如“如果我通过 7,那么结果应该是菜单 id 7 的所有子项和子项”
如果我通过了 7,那么我想要菜单 ID 为 7 的所有父级和超级父级。
在发布此问题之前,我在*** 上找到了几篇文章,但他们要求实施代码优先方法。以下是Entity Framework Self Join、Most efficient method of self referencing tree using Entity Framework之前在***上发布的问题
【问题讨论】:
可能的双份:***.com/questions/1308158/… 一个可能的解决方案是通过使用 TSQL 递归查询并返回行的 TVF(表值函数)。 @xanatos :我无法与数据库交互。我有菜单类对象的静态列表。这就是为什么我需要用 EF 来做。 【参考方案1】:我不确定您是否意识到这一点,但 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 实例的所有父级和所有子级。注意效率很糟糕。但这是一个不同的问题。在我的性能测试表明我的应用程序存在瓶颈之前,我不会优化代码。
有趣的引语:“过早的优化是万恶之源。” - Donald Knuth
【讨论】:
Part i 可以通过以下代码达到父母和孩子最高一级'List 添加了代码示例。它未经测试,因此您需要在这里和那里进行更改。但这是一般的想法。我重新阅读了您的类定义,对您为什么调用 Nullable以上是关于如何实现递归自连接实体框架?的主要内容,如果未能解决你的问题,请参考以下文章