如何选择连接两个表的子行

时间:2018-05-22 12:29:49

标签: c# lambda entity-framework-6

我有两张桌子:

1-屏幕(ID,IsCheck,ParentID,IsActive)

2- RoleScreen(ID,RoleID,ScreenID)

现在我有一个RoleID的整数列表。我想选择列表RoleID中存在的所有屏幕以及IsCheck为false的所有子屏幕。 RoleScreen表中不存在子屏幕ID。

我尝试了以下代码,但它没有返回子屏幕,IsCheck = false:

  this.context.Screens.Where(x => (x.IsActive == true) && 
                                  (
                                    (x.RoleScreens.Any(y => listUserRoleIDs.Any(z => z == y.RoleID))) ||
                                    (x.RoleScreens.Any(y => x.IsCheck== false && y.ScreenID == x.ParentID && listUserRoleIDs.Any(z => z == y.RoleID)))
                                  )).ToList();                  

请指导我做错了什么。

2 个答案:

答案 0 :(得分:0)

问题在这里

(x.RoleScreens.Any(y => x.IsCheck== false && y.ScreenID == x.ParentID && listUserRoleIDs.Any(z => z == y.RoleID)))

我不完全确定你想要什么,但如果你想要它如何写它并想要任何一个孩子那么它应该是:

(x.RoleScreens.Any(y => x.IsCheck== false && y.ScreenID == x.ParentID))

因为listUserRoleIDs.Any(z => z == y.RoleID)会过滤掉所有没有RoleID的孩子。

另一方面,如果你想让所有有屏幕角色的孩子都有角色那么最好把它分成两部分:

var Parents = this.context.Screens.Where(x => (x.IsActive == true) && 
                                    (x.RoleScreens.Any(y => listUserRoleIDs.Any(z => z == y.RoleID))));

var Children = this.context.Screens.Where(x => (x.IsActive == true) && (x.IsCheck== false) && (Parents.Any(y => x.ParentID == y.ScreenID)));

var List = Parents.Union(Children).ToList();

答案 1 :(得分:0)

假设您有以下型号

  public class Screen
  {
      public Guid ID { get; set; }
      public bool IsCheck { get; set; }
      public Guid ParentID { get; set; }
      public bool IsActive { get; set; }
      public Screen Parent { get; set; }
      public ICollection<Screen> Children { get; set; }
      public RoleScreen RoleScreen { get; set; }
  }

  public class RoleScreen
  {
      public Guid ID { get; set; }
      public Guid RoleID { get; set; }
      public Guid ScreenID { get; set; }
      public Screen Screen { get; set; }
  }

你想要检索:

  • 属于给定角色ID列表的所有屏幕
  • IsCheckfalse
  • 的给定屏幕的所有子屏幕
  • 不属于RoleScreens
  • 的所有子屏幕

简而言之,它会检索角色ID列表及其子屏幕中指定的任何屏幕。 然而,这个问题最终可能会导致子屏幕的子屏幕在其列表中有其父级(递归问题)。 但是,如果您只对直系孩子感到满意,则此查询将满足您的需求:

  this.context.Screens.Where(x => (x.IsActive == true) && 
                                  (
                                    //Retrieve all Screen designated in RoleScreen
                                    (x.RoleScreens.Any(y => listUserRoleIDs.Any(z => z == y.RoleID))) ||
                                      //Retrieve all Child Screens
                                      ((x.Parent != null)
                                                         //Retrieve all Child Screens that don't have role assignment
                                                         && ((x.RoleScreen == null) || 
                                                         // Retrieve immediate children of the Screen designated in RoleScreen
                                                         // this part will need to be recursed somehow that is difficult if not utterly costly or impossible in classic linq
                                                         ((x.Parent.RoleScreens.Any(y => listUserRoleIDs.Any(z => z == y.RoleID)))
                                                           && (x.IsCheck == false))))
                                  )).ToList();

免责声明:我实际上没有测试过该查询。拿着谷物和大量的盐。 我希望有人能提出更好的质询。