Дозвуковой 3 Союз Возможно?

У меня есть такая схема. Меню->Pages->PageRoles->ASPNetRoles

Меню имеет 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);

РЕДАКТИРОВАТЬ:

Я могу получить результаты в SQL через LEFT OUTER JOINS (см. Ниже), но снова перевести это в 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;

3 ответа

Похоже, что вы столкнулись с ошибкой в ​​реализации Union/Concat в SubSonic, вы должны сообщить об этом на сайт Google Code. Вы должны просто быть в состоянии сделать следующее, что, я уверен, вы уже сработали:

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;

Если SQL-запросы, сгенерированные для заполнения ваших анонимных типов, не совпадают, ни в коем случае: вы должны сделать что-то вроде этого:

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

И, конечно, это подразумевает двойной запрос к вашей базе данных.

Да, я тот, кто сообщает о проблеме LEFT OUTER JOIN. Роб сказал мне, что проблема в синтаксическом анализаторе Linq (подразумевается провайдер Iqueryable). Я думаю, что это серьезная проблема, потому что если вы не можете сделать больше, чем просто основные запросы - вы не можете работать с ним вообще...

так что толкните робота, чтобы исправить это как можно скорее.:-).

Захи.

Другие вопросы по тегам