2013-04-18 2 views
0

나는 기본적으로 여러 부서가있는 기관 인 하위 개체 목록이있는 개체를 가지고 있습니다. 부서는 부서의 부울 속성을 기반으로 비활성화되거나 활성화 될 수 있습니다. 장애가있는 부서가 하나 이상있을 때 기관의 자산을 거짓으로보고 싶습니다. 내 부분 기관 클래스에 다음 코드를 가지고 :Entity Framework 성능 - 어떻게 작동합니까?

public bool AllSet 
{ 
    get 
    { 
     return !(Departments.Where(i => i.Active == false && i.IsDeleted == false).Count() > 0); 
    } 
} 

이 작동하지만, 내가 가진 때 분명히 나는, 기관의 목록 크롤링 및 메모리 사용량 급증에 속도가 느려 보여줍니다 내 페이지의 성능을 사용할 수 여기에 근본적으로 잘못된 것을하는 사람은 누구나이 일을 할 수있는 다른 방법이 있습니까?

WORKING 솔루션은

var institutions = from x in ent.Institutions let hasDepartments = 
!x.Departments.Any(d => d.Active == false && d.IsDeleted == false) select new { 
       FullTitle = x.Title + " - " + x.Address.Line1 + ", " + x.Address.City + ", " + x.Address.State, Department = x, AllSet = hasDepartments, Guid = x.Guid 
      }; 
      instList.DataSource = institutions; 

답변

1

다음 쿼리를 사용하면 성능에 별 차이가 없습니다. 그러나 주요 문제는 Linq is unformformant입니다. 정의에 따라 런타임에 SQL 쿼리를 생성하므로 많은 양의 메타 데이터가 생성됩니다. NET 4.5가이 점에 관해서는 넷 4보다 오버 헤드가 낮다는 것을 알게 될 것입니다.

첫 번째 쿼리에 많은 비용이 드는 것으로 보이는 경우 뷰 만들기 프로세스 때문일 수도 있습니다. 사전 컴파일 된보기를 살펴볼 수 있습니다. 그러나 궁극적으로 속도가 필요한 경우 다른 곳을보십시오. 아마 심지어 인라인 SQL.

public bool AllSet 
{ 
    get 
    { 
     return !(Departments.Any(i => i.Active == false && i.IsDeleted == false)); 
    } 
} 

편집 : 방금 귀하의 실제 문제를 인식했습니다. AllSet은 Institution 클래스의 메소드로, 엄격한 루프에서 호출하는 것 같습니다. Lazy 로딩 때문에 "작동"한다고 가정합니다.

이것은 각 루프가 데이터베이스 호출을 할 때 매우 심각합니다. 이는 IO/대기 시간에 걸려서 매우 느려질 것입니다. 또한 데이터베이스에서 bool을로드하는 대신 각 관련 모든 Department이 필요에 따라로드 된 다음 .Count()이 .net에서 로컬로 실행됩니다 (따라서 큰 메모리 풋 프린트).

활성 부서가있는 경우 각 기관과 함께 프리 페치를 시도하십시오.

var institutions = from x in context.Institutions 
        where {blah} 
        let hasDepartments = x.Departments.Any(d => d.Active == false 
            && i.IsDeleted == false) 
        select new { Department = x, AllSet = hasDepartments}; 
foreach(var institution in institutions) 
{ 
    //DO STUFF 
} 

전체적으로 실제 WTF는 EF 지연로드에 의존한다는 것입니다.

+0

또는 EAGER 부서를로드 할 수 있지만 일부 부울뿐만 아니라 모든 Deparments를로드하는 것을 의미합니다. – Aron

+0

나는 쿼리로이 모든 작업을하는 것을 좋아합니다. 내일 시도하고 다시 게시 할 것입니다. – box86rowh

+0

귀하의 도움에 감사 드리며 원래의 질문에 대한 귀하의 대답의 다양성, 나는이 방법을 사용하여 앞으로 더 큰 목록을 채울 것입니다. – box86rowh

1

당신은 사용할 수 있습니다

public bool AllSet 
{ 
    get 
    { 
     return !(Departments.Count(i => i.Active == false && i.IsDeleted == false) > 0); 
    } 
} 

, 당신의 EF 성능 향상이 link을 확인하는 팁이 있습니다. (EF를 사용하는 사용자는이 값을 읽을 가치가 있습니다.)

+0

이 방법은 메모리를 조금씩 사용하므로 (전혀 다를 수 있음) 여전히 매우 느립니다. 매우 이상합니다. – box86rowh

관련 문제