C# 实体框架下的自引用

C# 实体框架下的自引用,c#,entity-framework,C#,Entity Framework,代码代表了我的小范围问题: public class Category { public Guid CategoryID { get; set; } public string Name { get; set; } public Guid? ParentID { get; set; } public bool IsTop { get; set; } public string Description { get; set; } public vi

代码代表了我的小范围问题:

public class Category
{
    public Guid CategoryID { get; set; }
    public string Name { get; set; }
    public Guid? ParentID { get; set; }
    public bool IsTop { get; set; }
    public string Description { get; set; }

    public virtual Category parentCategory { get; set; }
}
当我在实体框架中使用这个类时,它只生成父类别和子类别的一个关系

如何在SQL Server中区分属性并生成两种不同的关系?一种用于获取所有子类别(子关系的子关系(递归自上而下)),另一种用于获取所有父类别(父关系的父关系(递归自下而上))?大概是这样的:

public virtual ICollection<Category> childCategories { get; set;} 
public virtual ICollection<Category> parentCategories { get; set;}
公共虚拟ICollection子类别{get;set;}
公共虚拟ICollection父类别{get;set;}

我用modelBuilder尝试过,但从那里我只能得到一个详细级别。

我遇到了一个问题,在我的一个项目中,检索到深度为n的所有子节点,作为模型中员工表上的典型主管/员工自引用关系。正如Slauma和Milracle指出的,EF不会帮助您检索指定父节点下深度为n的所有节点。但是,我能够使用我的存储库中的解决方案解决这个问题。请注意,我的目标不仅是检索所有子节点,而且要快速检索,因为对于顶级管理层来说,使用递归LINQ查询需要两分钟以上的时间。使用此方法,它现在可以在不到两秒钟的时间内执行

public IEnumerable<string> GetAllSubordinateEmployeeIdsByUserId(string userId)
{
    // Retrieve only the fields that create the self-referencing relationship from all nodes
    var employees = (from e in GetAllEmployees()
                     select new { e.Id, e.SupervisorId });
    // Dictionary with optimal size for searching
    Dictionary<string, string> dicEmployees = new Dictionary<string, string>(employees.Count() * 4);
    // This queue holds any subordinate employees we find so that we may eventually identify their subordinates as well
    Queue<string> subordinates = new Queue<string>();
    // This list holds the child nodes we're searching for
    List<string> subordinateIds = new List<string>();

    // Load the dictionary with all nodes
    foreach (var e in employees)
    {
        dicEmployees.Add(e.Id, e.SupervisorId);
    }

    // Get the key (employee's ID) for each value (employee's supervisor's ID) that matches the value we passed in
    var directReports = (from d in dicEmployees
                         where d.Value == userId
                         select d.Key);

    // Add the child nodes to the queue
    foreach (var d in directReports)
    {
        subordinates.Enqueue(d);
    }

    // While the queue has a node in it...
    while (subordinates.Count > 0)
    {
        // Retrieve the children of the next node in the queue
        var node = subordinates.Dequeue();
        var childNodes = (from e in dicEmployees
                          where e.Value == node
                          select e.Key);
        if (childNodes.Count() != 0)
        {
            // Add the child nodes to the queue
            foreach (var c in childNodes)
            {
                subordinates.Enqueue(c);
            }
        }
        // Add the node from the queue to the list of child nodes
        subordinateIds.Add(node);
    }

    return subordinateIds.AsEnumerable();
}
public IEnumerable GetAllSubstanceEmployeeIDsbyUserId(字符串userId)
{
//仅检索从所有节点创建自引用关系的字段
var employees=(来自GetAllEmployees()中的e)
选择新的{e.Id,e.SupervisorId});
//具有最佳搜索大小的词典
Dictionary DiceEmployees=新字典(employees.Count()*4);
//此队列包含我们找到的任何下属员工,以便我们最终也可以确定他们的下属
队列下属=新队列();
//此列表包含我们正在搜索的子节点
List SUBSERVIDES=new List();
//加载包含所有节点的字典
foreach(员工中的var e)
{
添加(e.Id,e.SupervisorId);
}
//获取与我们传入的值匹配的每个值(员工的主管ID)的键(员工ID)
var directReports=(从d到d)
其中d.Value==userId
选择d键);
//将子节点添加到队列中
foreach(directReports中的变量d)
{
下属。排队(d);
}
//当队列中有一个节点时。。。
而(下属数>0)
{
//检索队列中下一个节点的子节点
var node=substances.Dequeue();
var childNodes=(来自DiceEmployees中的e)
其中e.Value==节点
选择e.Key);
if(childNodes.Count()!=0)
{
//将子节点添加到队列中
foreach(childNodes中的var c)
{
下属。排队(c);
}
}
//将队列中的节点添加到子节点列表中
添加(节点);
}
返回subfiliards.AsEnumerable();
}

另外,作为一个脚注,在本文的帮助下,我能够提高字典中查找的效率。

每个类别有多个父级还是只有一个父级?我也不明白你到底想要什么。是否需要一个集合
parentCategories
,其中包含从树到根的所有类别?如果是,这将不是导航属性,而是某种类型的计算或遍历的结果。EF不会帮你,你必须自己编写代码来创建这样的集合。是的,没错。我想要这样的东西,它给我树下所有的子类别和树上所有的父类别一样。。。是的,我意识到EF在这种情况下不会有帮助,所以我做了一些IEnmuerable的递归循环,它对我很有用。。感谢您的支持此解决方案不是仅在两个级别进行搜索吗?我错过什么了吗?