2009-06-24 5 views
1

WebPages라는 IQueryable 속성이있는 Menu 클래스가 있습니다. 다음 문장에서 일치 항목을 기반으로 메뉴 항목을 반환하지만 Webpages 속성을 포함해야합니다. 여기 제가 지금 가지고있는 것이 있습니다. 내가 노력하고 무엇을 LINQ IQueryable Help

var allCategories = Menu.All().Where(x => x.CategoryID == 4 && x.Visible) 

나는

var allCategories = Menu.All().Where(x => x.CategoryID == 4 && x.Visible && x.WebPages.Roles.Contains(User.Identity.Name)) 

컴파일되지 않습니다 .. 웹 페이지 클래스에서 같은 것을 속성을 확인하기 위해 그것을 확장해야하지만 난 당신의 JIST를 얻을 희망 할 것.

참고 : Webpage 속성은 CategoryID가 아닌 PageID로 채워지지만 차이가 있는지 확실하지 않습니까 ??

다음은 내 수업 개요입니다.

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

이 그것을 어떻게해야 ...

public IQueryable<WebPage> WebPages 

public IEnumerable<WebPage> WebPages 

내가 LINQ 쿼리는 IEnumerable을 반환 생각을 변경해보십시오. 웹 페이지를 말할 필요가 있습니다. 특정 메뉴가 지정된 역할을 가진 웹 페이지를 포함하고 있으면 true를 반환합니다.

var allCategories = menus.Where(menu => menu.CategoryID == 1 && menu.Visible && menu.WebPages.Any(webPage => webPage.Roles.Contains(roleToSearchFor))); 

그래서 추가해야 할 핵심 비트가 있습니다. 그것은 즉시 일치하는 항목을 발견로보고 그만 것 같은 모든() 기능을 사용

menu.WebPages.Any(webPage => webPage.Roles.Contains(roleToSearchFor)) 

매우 효율적입니다.

() 다음 카운트()는 모든 상대를 만나 모든 웹 페이지를 반복하고 훨씬 덜 효율적이 될 것이다, 그래서 다음을 계산하는 결과를 반복 할 어디 을 사용합니다.

다음은 전체 소스 코드 예제입니다.

namespace DoctaJonez.TestingBrace 
    { 
     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; set; } 
     } 

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

     public static class Launcher 
     { 
      /// <summary> 
      /// The Main entry point of the program. 
      /// </summary> 
      static void Main(string[] args) 
      { 
       Menu myMenu1 = new Menu 
       { 
        ID = 1, 
        CategoryID = 1, 
        PageID = 1, 
        Visible = true, 
        WebPages = new List<WebPage>() 
        { 
         new WebPage { ID = 1, Roles = "Role1" }, 
         new WebPage { ID = 1, Roles = "Role2" }, 
         new WebPage { ID = 1, Roles = "Role3" }, 
        }.AsQueryable() 
       }; 

       Menu myMenu2 = new Menu 
       { 
        ID = 1, 
        CategoryID = 1, 
        PageID = 1, 
        Visible = true, 
        WebPages = new List<WebPage>() 
        { 
         new WebPage { ID = 1, Roles = "Role3" }, 
         new WebPage { ID = 1, Roles = "Role4" }, 
         new WebPage { ID = 1, Roles = "Role5" }, 
        }.AsQueryable() 
       }; 

       Menu myMenu3 = new Menu 
       { 
        ID = 1, 
        CategoryID = 1, 
        PageID = 1, 
        Visible = true, 
        WebPages = new List<WebPage>() 
        { 
         new WebPage { ID = 1, Roles = "Role5" }, 
         new WebPage { ID = 1, Roles = "Role6" }, 
         new WebPage { ID = 1, Roles = "Role7" }, 
        }.AsQueryable() 
       }; 

       List<Menu> menus = new List<Menu>() { myMenu1, myMenu2, myMenu3 }; 

       string roleToSearchFor = "Role3"; 

       var allCategories = menus.Where(menu => menu.CategoryID == 1 && menu.Visible && menu.WebPages.Any(webPage => webPage.Roles.Contains(roleToSearchFor))).ToList(); 

       return; 
      } 
     } 
0

당신이 짝짓기를 위해

0

DoctorJonez 감사합니다 !!!

나는 여기에 더 많은 공간을두고 있습니다.내가 이것을 실행하면 내가 얻을 나는 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' + '%') 
) 

을 그대로 나는 11 개 기록을 얻을

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

를 사용하는 경우 그러나 나는 단지 1 페이지 id 세트, 메뉴 테이블에서 11 개 레코드가 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])) 
) 

이것은 Subsonic의 버그입니까, 올바르게 이해하지 못합니까?

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 세트. 사용자의 역할이 웹 페이지에 없다면 나는 내 결과에서 그것을보고 싶지 않습니다. 이 내용은 메뉴 항목이 적절한 역할이있는 페이지에 가입 선택해야

var menuItems = 
    from menuItem in Menu.All() 
     where menuItem.Visible 
      and (
       menuItem.WebPages.Contains(
        webPage => webPage.Roles.Contains(
         "role" 
        ) 
       ) 
       or menuItem.PageIsNull 
      ) 
     select menuItem; 

: 나는 문제를 정확하게 이해한다면

+0

답이 아닌 질문에 대한 자세한 내용이므로이 정보를 포함하도록 질문을 편집 할 수 있습니다. – CoderDennis

1

, 당신이 뭔가를 할 수 있습니다.

+0

PageID가 null 인 곳이 필요합니다. – Jon

+0

위의 쿼리를 편집하여 null 페이지 확인을 포함합니다. 어떤 구문을 사용해야 하는지를 알기 위해 객체 모델에 대해 충분히 알지 못합니다. –

관련 문제