1

我有一个这样的模式。菜单->页面->PageRoles->ASPNetRoles

Menu 有一个 CategoryID。

我想返回 CategoryID 为 6 的所有菜单项。

某些菜单项具有 PageID 的外键。页面可以针对它们具有 1 个或多个角色。我可以检查当前登录的用户角色,并通过加入表格来确保它们在结果中。

我想返回 CategoryID 为 6 的所有菜单项,对于那些具有 PageID 的用户角色必须是分配给页面的那些角色。

我能想到的唯一方法是建立一个工会,但是当我在 Subsonic 中这样做时它失败了。以下作品。

    var dd = (from menu in Menu.All().Where(x => x.PageID == null && x.CategoryID == 6) select menu);
    var ss =  from menu2 in Menu.All()
              join pages in WebPage.All() on menu2.PageID equals pages.ID
              join pagesRoles in PageRole.All() on pages.ID equals pagesRoles.PageID
              join roles in aspnet_Role.All() on pagesRoles.RoleId equals roles.RoleId
              where Roles.GetRolesForUser().Contains(roles.RoleName) &&
              menu2.CategoryID == 6
              select menu2;

我如何组合结果?

这样做会失败:

var dd = (from menu in Menu.All().Where(x => x.PageID == null) select menu).Union(
              from menu2 in Menu.All()
              join pages in WebPage.All() on menu2.PageID equals pages.ID
              join pagesRoles in PageRole.All() on pages.ID equals pagesRoles.PageID
              join roles in aspnet_Role.All() on pagesRoles.RoleId equals roles.RoleId
              where Roles.GetRolesForUser().Contains(roles.RoleName)
              select menu2);

编辑:

我可以通过 LEFT OUTER JOINS(见下文)获得 SQL 中的结果,但再次将其转换为 LINQ/Subsonic 失败。

SELECT * FROM MENU M

LEFT OUTER JOIN WEBPAGE P
ON P.ID = M.PAGEID

LEFT OUTER JOIN PAGEROLES R
ON R.PAGEID = P.ID

LEFT OUTER JOIN ASPNET_ROLES A
ON A.ROLEID = R.ROLEID

WHERE ((CATEGORYID = 1) OR ( CategoryID = 1 AND A.ROLENAME IN ('ADMINISTRATOR','USER')))

即使像这样简单的事情也会失败

var resu = from p in db.Menus 
join pages in db.WebPages on p.PageID equals pages.ID 
into temp from pages in temp.DefaultIfEmpty()
select p;
4

3 回答 3

1

看起来您在 SubSonic 的 Union/Concat 实现中遇到了一个错误,您应该将它报告给 google 代码站点。您应该能够执行以下操作,我很确定您已经解决了:

var unionList = dd.Concat(ss).ToList<Menu>();

同时,以下内容应该非常接近您所追求的外部联接:

var ss =  from menu in Menu.All()
    group join pages in WebPage.All() on menu2.PageID equals pages.ID
      into pagesMenu from pm in pagesMenu.DefaultIfEmpty()
    group join pagesRoles in PageRole.All() on pages.ID equals pagesRoles.PageID
      into pagesRolesPages from prp in pagesRolesPages.DefaultIfEmpty()
    group join roles in aspnet_Role.All() on pagesRoles.RoleId equals roles.RoleId
      into pagesRolesRoles from prr in pagesRolesRoles.DefaultIfEmpty()
  where menu.PageID == null || 
    (Roles.GetRolesForUser().Contains(roles.RoleName) && menu2.CategoryID == 6)
  select menu;
于 2009-06-29T16:32:51.203 回答
0

如果为填充您的匿名类型而生成的 SQL 查询不匹配,则没有办法:您必须执行以下操作:

dd.ToList().AddRange(ss.ToList());

当然,这意味着对您的数据库的双重请求。

于 2010-01-04T05:48:00.793 回答
0

是的,我是报告 LEFT OUTER JOIN 问题的人。rob 告诉我问题出在 Linq 解析器(Iqueryable provider impl)。我认为这是一个主要问题,因为如果你不能做的不仅仅是基本查询 - 你根本无法使用它......

所以推动抢劫尽快修复它。:-)。

扎希

于 2009-06-30T06:59:10.323 回答