2014-10-19 1 views
1

MVC 응용 프로그램 용 검색 논리를 작성하고 간단하게 설명하겠습니다.여러 관련 엔티티가있는 엔티티에 대한 성능 및 유니온

투영법을 사용하기 위해 Linq to Entities 쿼리를 작성하는 데 며칠을 보냈습니다. 아래에 생성 된 SQL 문을 살펴볼 때까지 모두 표면에 좋았습니다. Gasp!

다음 JOINs, FROMs, INCLUDEs를 시도하면서 SQL 문에서이 UNION 문을 제거하기 위해 며칠을 보냈다.로드 된 관련 엔티티에 내/외부 외부 조인을 제공하는 모든 작업.

하지만이 작업을 성공적으로 수행하지 못했지만이 시점에서 여전히 고생했습니다.

어떤 점

고려해야 할 :

  • L2E 쿼리 프로젝션 여러 관련 (자식) 엔티티가 들어 맞는
  • 만든 요약 클래스 (여기에 어떤 문제를이 즉 노조의 원인이 나쁜 설계가 아닌 경우) 익명의 타입, 예. StudentSummary
  • 요약 클래스는 성능상의 이유로 엔티티 개체 열의 열 몇 개만 포함합니다. 초기 검색에서 모든 열을 반환 할 필요가 없습니다.
  • 최근 PredicateBuilder를 사용하여 검색에서 학생을 반환하기 시작했습니다. 전문화 된 남학생 ...이 분야의 모든 것이 좋습니다 (지금까지). 여기

은 (코드 전용 속성을 숨길 변경 - 오타가있을 수 있습니다) 지금까지 한 일이다

query = from s in context.Students 
    select new StudentSummary 
    { 
     StudentID = s.StudentID, 
     Title = s.Title, 
     FullName = s.FullName, 
     Qualifications = s.Qualifications, 
     Gender = s.Gender, 
     CampusSummaries = (
        from c in s.Campuses 
        select new CampusSummary 
        { 
         Name = c.Name, 
         LocationSummary = new LocationSummary 
         { 
          State = c.Location.State 
         } 
        }), 
        SpecializationSummaries = (
            from sp in s.StudentSpecializations 
            select new StudentSpecializationSummary 
             { 
              StudentSpecializationID = sp.StudentSpecializationID, 
              SpecializationSummary = new SpecializationSummary 
              { 
               Name = s.Specialization.Name 
              } 
             }), 
        SubSpecializationSummaries = (
            from ssp in s.StudentSubSpecializations 
            select new StudentSubSpecializationSummary 
             { 
              StudentSubSpecializationID = ssp.StudentSubSpecializationID, 
              SubSpecializationSummary = new SubSpecializationSummary 
              { 
               Name = s.SubSpecialization.Name 
              } 
             }) 
}; 

내 투사 문 엔티티 프레임 워크는 다음과 같은 SQL UNION 문을 생성하게 나타납니다,

{SELECT 
[UnionAll1].[StudentID] AS [C1], 
[UnionAll1].[StudentID1] AS [C2], 
[UnionAll1].[Title] AS [C3], 
[UnionAll1].[FullName] AS [C4], 
[UnionAll1].[Qualifications] AS [C5], 
[UnionAll1].[Gender] AS [C6], 
[UnionAll1].[C1] AS [C9], 
[UnionAll1].[StudentSpecializationID] AS [C10], 
[UnionAll1].[StudentSpecializationID1] AS [C11], 
[UnionAll1].[StudentSpecializationID2] AS [C12], 
[UnionAll1].[Name] AS [C13], 
[UnionAll1].[C2] AS [C14], 
[UnionAll1].[C3] AS [C15], 
[UnionAll1].[C4] AS [C16], 
[UnionAll1].[C5] AS [C17] 
FROM (SELECT 
    CASE WHEN ([Join1].[StudentSpecializationID] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1], 
    [Extent1].[StudentID] AS [StudentID], 
    [Extent1].[StudentID] AS [StudentID1], 
    [Extent1].[Title] AS [Title], 
    [Extent1].[FullName] AS [FullName], 
    [Extent1].[Qualifications] AS [Qualifications], 
    [Extent1].[Gender] AS [Gender], 
    [Join1].[StudentSpecializationID] AS [StudentSpecializationID], 
    [Join1].[StudentSpecializationID] AS [StudentSpecializationID1], 
    [Join1].[StudentSpecializationID] AS [StudentSpecializationID2], 
    [Join1].[Name] AS [Name], 
    CAST(NULL AS int) AS [C2], 
    CAST(NULL AS int) AS [C3], 
    CAST(NULL AS int) AS [C4], 
    CAST(NULL AS varchar(1)) AS [C5] 
    FROM [dbo].[Student] AS [Extent1] 
    LEFT OUTER JOIN (SELECT [Extent2].[StudentSpecializationID] AS [StudentSpecializationID], [Extent2].[StudentID] AS [StudentID], [Extent3].[Name] AS [Name] 
     FROM [dbo].[StudentSpecialization] AS [Extent2] 
     INNER JOIN [dbo].[Specialization] AS [Extent3] ON [Extent2].[SpecializationID] = [Extent3].[SpecializationID]) AS [Join1] ON [Extent1].[StudentID] = [Join1].[StudentID] 
UNION ALL 
    SELECT 
    2 AS [C1], 
    [Extent4].[StudentID] AS [StudentID], 
    [Extent4].[StudentID] AS [StudentID1], 
    [Extent4].[Title] AS [Title], 
    [Extent4].[FullName] AS [FullName], 
    [Extent4].[Qualifications] AS [Qualifications], 
    [Extent4].[Gender] AS [Gender], 
    CAST(NULL AS int) AS [C2], 
    CAST(NULL AS int) AS [C3], 
    CAST(NULL AS int) AS [C4], 
    CAST(NULL AS varchar(1)) AS [C5], 
    [Join3].[StudentSubSpecializationID] AS [StudentSubSpecializationID], 
    [Join3].[StudentSubSpecializationID] AS [StudentSubSpecializationID1], 
    [Join3].[StudentSubSpecializationID] AS [StudentSubSpecializationID2], 
    [Join3].[Name] AS [Name] 
    FROM [dbo].[Student] AS [Extent4] 
    INNER JOIN (SELECT [Extent5].[StudentSubSpecializationID] AS [StudentSubSpecializationID], [Extent5].[StudentID] AS [StudentID], [Extent6].[Name] AS [Name] 
     FROM [dbo].[StudentSubSpecialization] AS [Extent5] 
     INNER JOIN [dbo].[SubSpecialization] AS [Extent6] ON [Extent5].[SubSpecializationID] = [Extent6].[SubSpecializationID]) AS [Join3] ON [Extent4].[StudentID] = [Join3].[StudentID]) AS [UnionAll1] 
ORDER BY [UnionAll1].[StudentID1] ASC, [UnionAll1].[C1] ASC} 

노조가 여기에 사용되는 이유는 확실하지 않다 : - 아래 조각 만 (오타가있을 수 있습니다 고유의 속성을 숨길 변경 코드)입니다. 아마도 나는 투영을 잘못 사용하고있을 것입니다. 두 개 이상의 예측이 L2E 문에 포함되어있을 때 알아 봤지만 SQL에 UNIONS가 나타납니다.

투영을 제거하여 다른 방향으로 시도했지만 조인, 시작을 사용하여 성공적으로 시도하지 못했습니다 ... 관련된 자식 엔터티를 반환 할 수없는 것 같습니다.

성능상의 이유로 요약 개체를 사용하고 있으므로 포함을 사용할 수 없습니다.

올바르게 올바르게 적용 할 것인지, 즉 중첩 된 관련 하위 항목을 반환하는 올바른 방향으로 가고 있는지 궁금해합니다. 아마도 나는 예를 들어 정확한 결과를 반환해야합니다. 학생, 캠퍼스, 전문화 ... 같은 수준에있는 모든 객체, 즉 계층 구조를 제거합니다.

질문 :

나는 T-SQL과 함께이 내장 내가 INNER & LEFT OUTER는 관련 하위 하위 항목을 반환하고 학생들을 필터링하는 조인 사용하는 것입니다 경우. 이것이 내가 Linq와 Entities를 이루기 위해 노력하고있는 것입니다. 어떻게해야합니까? 예 : 조인, 프로젝션 또는 무엇이든간에 ... (UNION 및 캐스트 (NULL) 없음 ...)

내가 올바른 방향으로 나를 가리키고 있다고해도, 나는 정말로 여기에서 붙어있어서 도움이된다. 감사.

답변

0

쿼리가 제대로 수행되지 않습니까? 그렇지 않은 경우에는 생성 된 SQL에 대해 걱정하지 마십시오. 사실이 작업을 수행하는 가장 좋은 방법은 union all을 사용하는 것일 수 있습니다. 여러 조인을 사용하여 하나의 매우 복잡한 쿼리를 만드는 것이 여러 개의 간단한 쿼리를 조합하는 것보다 느릴 수 있습니다. union all

+0

쿼리가 적은 수의 레코드로 잘못 실행되지는 않지만 SQL 프로파일 링을 통해 확인해야합니다. 그러나 좋은 포인트 재 조합 모두 대 여러 조인 - 생각하지 않았다. 확인을 위해 이것에 대해 읽을 것입니다. 고마워,이 도움이됩니다. –

관련 문제