亚音速3联盟可能吗?

发布于 2024-07-26 00:22:43 字数 2011 浏览 3 评论 0原文

我有一个像这样的架构。 菜单->页面->PageRoles->ASPNetRoles

菜单有一个CategoryID。

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

某些菜单项的外键为 PageID。 页面可以有 1 个或多个角色。 我可以检查当前登录的用户角色,并通过连接表确保它们位于结果中。

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

我能想到的唯一方法是建立一个联盟,但当我在亚音速中这样做时,它失败了。 以下作品。

    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;

I have a schema like so. Menu->Pages->PageRoles->ASPNetRoles

Menu has a CategoryID.

I want to return all Menu items with a CategoryID of 6.

Some Menu items have a foreigh key of PageID. Pages can have 1 or more roles against them. I can check the currently logged in users roles and make sure that they are in the results by joining the tables.

I want to return all Menu items with a CategoryID of 6 and for those that have PageID's the users role must be in those roles assigned to the page.

The only way I can think is to do a union but when I do this in Subsonic it fails. The following works.

    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;

How do I combine the results?

Doing this it fails:

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);

EDIT:

I can get the results in SQL via LEFT OUTER JOINS (See Below) but again translating this into LINQ/Subsonic fails.

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')))

Even something simple like this fails

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;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

回忆凄美了谁 2024-08-02 00:22:43

看起来您在 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;

It looks like you're bumping into a bug in SubSonic's implementation of Union/Concat, you should report it to the google code site.
You should just be able to do the following, which I'm pretty sure you'd already worked out:

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

In the meantime the following should be pretty close to the outer join you're after:

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;
虫児飞 2024-08-02 00:22:43

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

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

扎希。

Yeh, I'm the one that reports the LEFT OUTER JOIN problem.
rob told me that the problem is by the Linq parser (Iqueryable provider impl).
i think this is major issue because if u can't do more than just basic querys - you can't work with it at all...

so push rob to fix it ASAP. :-).

zahi.

仅此而已 2024-08-02 00:22:43

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

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

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

If the SQL queries generated to fill your anonymous types doesn't match, no way: you must do something like this:

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

And of course, this implies double request to your database.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文