2009-06-24 55 views
0

我有11條記錄中的菜單表,只有1個有PAGEID一套但是如果我用重新設計SQL到亞音速LINQ

var test = Menu.All().Where(
    x => x.WebPages.Any(
     pages => pages.Roles.Contains(Roles.GetRolesForUser()[0]) 

我得到11個記錄作爲SQL運行是這個

SELECT [t0].[CategoryID], [t0].[CreatedBy], [t0].[CreatedOn], 
    [t0].[ID], [t0].[ImageID], [t0].[ImageIDHover], [t0].[Locale], 
    [t0].[ModifiedBy], [t0].[ModifiedOn], [t0].[OrderID], [t0].[PageID], 
    [t0].[ParentID], [t0].[Title], [t0].[URL], [t0].[Visible] 
FROM [dbo].[Menu] AS t0 
WHERE EXISTS(
    SELECT NULL 
    FROM [dbo].[WebPage] AS t1 
    WHERE ([t1].[Roles] LIKE '%' + 'User' + '%') 
) 

如果我運行此我得到1個記錄

var test = Menu.All().Where(
    x => x.WebPages.Any(
     pages => pages.Roles.Contains(
     Roles.GetRolesForUser()[0]) && pages.ID == x.PageID)); 

這樣做的SQL是

SELECT [t0].[CategoryID], [t0].[CreatedBy], [t0].[CreatedOn], 
    [t0].[ID], [t0].[ImageID], [t0].[ImageIDHover], [t0].[Locale], 
    [t0].[ModifiedBy], [t0].[ModifiedOn], [t0].[OrderID], [t0].[PageID], 
    [t0].[ParentID], [t0].[Title], [t0].[URL], [t0].[Visible] 
FROM [dbo].[Menu] AS t0 
WHERE EXISTS (
    SELECT NULL 
    FROM [dbo].[WebPage] AS t1 
    WHERE (([t1].[Roles] LIKE '%' + 'User' + '%') AND 
     ([t1].[ID] = [t0].[PageID])) 
) 

Any()的問題是,只要有一條記錄退出,SQL就會返回數據並不重要。

我覺得有效,我想一個UNION SQL像下面,但我不知道我是怎麼重新設計是爲C#/亞音速

select m.* from menu m where pageid is null 
union 
select m.* from menu m 
join webpage p 
on p.id = m.pageid 
where p.roles like '%User%' 

我想回到所有菜單的記錄,併爲那些與PageID設置相應的WebPage具有用戶在其中的角色。如果用戶的角色不在WebPage中,那麼我不想在我的結果中看到它。

這裏是我的cutodwn類,亞音速產生

public partial class Menu: IActiveRecord 
    { 
     public int ID {get; set;} 
     public int CategoryID {get;set;} 
     public bool Visible {get;set;} 
     public int PageID {get;set;} 
     public IQueryable<WebPage> WebPages 
     { 
      get 
      { 

        var repo=NorthCadburyWebsite.Models.WebPage.GetRepo(); 
        return from items in repo.GetAll() 
         where items.ID == _PageID 
         select items; 
      } 
     } 
} 

public partial class WebPage: IActiveRecord 
    { 
     public int ID {get;set;} 
     public string Roles {get;set;} 
} 

回答

0

它肯定好像你可以只添加一種替代測試where子句來做到這一點。

var test = Menu.All() 
       .Where(x => x.PageID == null 
         || x.WebPages 
          .Any(pages => pages.Roles.Contains(Roles.GetRolesForUser()[0]) 
              && pages.ID == x.PageID)); 

EDIT

嘗試使用該Intersect方法,以查看是否有在DB中的作用和對用戶的角色之間的重疊。

var test = Menu.All() 
       .Where(x => x.PageID == null 
         || x.WebPages 
          .Any(pages => pages.Roles.Intersect(Roles.GetRolesForUser().Split(',')) 
              && pages.ID == x.PageID)); 
+0

這看起來很簡單!但是,如果我將WebPages作爲菜單的屬性,爲什麼需要添加「&& pages.ID == x.PageID」?作爲一個外鍵,爲什麼我需要添加它? – Jon 2009-06-24 13:55:56