c# – 使用Entity Framework进行自引用

前端之家收集整理的这篇文章主要介绍了c# – 使用Entity Framework进行自引用前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
代码代表我的问题的小规模:
  1. public class Category
  2. {
  3. public Guid CategoryID { get; set; }
  4. public string Name { get; set; }
  5. public Guid? ParentID { get; set; }
  6. public bool IsTop { get; set; }
  7. public string Description { get; set; }
  8.  
  9. public virtual Category parentCategory { get; set; }
  10. }

当我在Entity Framework中使用此类时,它只生成父类和子类的一个关系.

如何在语义上区分属性,并在sql Server中生成两个不同的关系,用于获取所有子类别(子关系的子项(递归自上而下)),另一个用于获取所有父类别(父项的父项) (递归自下而上))?像这样的东西:

  1. public virtual ICollection<Category> childCategories { get; set;}
  2. public virtual ICollection<Category> parentCategories { get; set;}

我尝试使用模型构建器,但从那里我只能获得一个级别的细节.

解决方法

在我的一个项目中,我遇到了将所有子节点检索到n深度的问题,作为模型中Employee表上的经典主管/员工自引用关系.正如Slauma和Milracle指出的那样,EF不会帮助您在指定父级下检索所有节点到n的深度.但是,我能够在我的存储库中使用 @L_502_0@来解决这个问题.请注意,我的目标不仅是检索所有子节点,而且要快速执行,因为使用递归LINQ查询需要超过两分钟的时间来进行最高级别的管理.使用此方法,它现在可在不到两秒的时间内执行.
  1. public IEnumerable<string> GetAllSubordinateEmployeeIdsByUserId(string userId)
  2. {
  3. // Retrieve only the fields that create the self-referencing relationship from all nodes
  4. var employees = (from e in GetAllEmployees()
  5. select new { e.Id,e.SupervisorId });
  6. // Dictionary with optimal size for searching
  7. Dictionary<string,string> dicEmployees = new Dictionary<string,string>(employees.Count() * 4);
  8. // This queue holds any subordinate employees we find so that we may eventually identify their subordinates as well
  9. Queue<string> subordinates = new Queue<string>();
  10. // This list holds the child nodes we're searching for
  11. List<string> subordinateIds = new List<string>();
  12.  
  13. // Load the dictionary with all nodes
  14. foreach (var e in employees)
  15. {
  16. dicEmployees.Add(e.Id,e.SupervisorId);
  17. }
  18.  
  19. // Get the key (employee's ID) for each value (employee's supervisor's ID) that matches the value we passed in
  20. var directReports = (from d in dicEmployees
  21. where d.Value == userId
  22. select d.Key);
  23.  
  24. // Add the child nodes to the queue
  25. foreach (var d in directReports)
  26. {
  27. subordinates.Enqueue(d);
  28. }
  29.  
  30. // While the queue has a node in it...
  31. while (subordinates.Count > 0)
  32. {
  33. // Retrieve the children of the next node in the queue
  34. var node = subordinates.Dequeue();
  35. var childNodes = (from e in dicEmployees
  36. where e.Value == node
  37. select e.Key);
  38. if (childNodes.Count() != 0)
  39. {
  40. // Add the child nodes to the queue
  41. foreach (var c in childNodes)
  42. {
  43. subordinates.Enqueue(c);
  44. }
  45. }
  46. // Add the node from the queue to the list of child nodes
  47. subordinateIds.Add(node);
  48. }
  49.  
  50. return subordinateIds.AsEnumerable();
  51. }

此外,作为脚注,我在这篇Dictionary optimization文章的帮助下,能够提高字典中的查找效率.

猜你在找的C#相关文章