2013-11-28 2 views
1

성능 문제가있는 SQL Server에서 Entity Framework를 사용하는 프로젝트 ASP.NET MVC3에서 작업하고 있습니다.Entity Framework - 쿼리 실행 성능 문제

EF 및 Linq를 사용하여 뷰/테이블에서 데이터를로드 할 때마다. SQL Server Profiler에서는 모든 조건이 프로파일 러에 나타나지 않기 때문에 모든 테이블/뷰 내용을 검색 할 수 있습니다. 나중에 LINQ에 의해 필터링됩니다 생각합니다.

맞습니까? SQL Server에서 처음에 필요한 데이터 만로드하는 방법?

var query = unitWork.City.GetFirstorDefault(item => item.City == cityCode); 

데이터 호출 예를 들어 우리의 데이터 영역의 추출 다음은

이 내 예제 코드입니다. 답장을 보내 주셔서 감사합니다. 여기

public class UnitOfWork : IUnitOfWork, IDisposable 
    { 

     #region CONSTRUCTOR 
     public UnitOfWork() 
     { 
      _context = new MyApplicationEntities(); //DataContext 
      _context.ContextOptions.LazyLoadingEnabled = true; 
      _context.ContextOptions.UseLegacyPreserveChangesBehavior = false; 
     } 
     #endregion 

     // DESC_RECHARGEABLE is a table in DB   
     public IGenericRepository<DESC_RECHARGEABLE> RepRechargeable 
     { 
      get{return _repRechargeable ?? (_repRechargeable = new GenericRepository<DESC_RECHARGEABLE>(_context));} 
     } 



} 

    public interface IGenericRepository<T> : ICollection<T> 
     where T : class 
    { 
     IEnumerable<T> Query(Func<T, bool> predicate); 

void Update(T entity); 

T GetFirstorDefault(Func<T, bool> predicate); 

IEnumerable<T> GetAll(); 

T GetByKey(Func<T, bool> predicate); 

bool Remove(T entity); 

void Add(T entity); 

     ObjectSet<T> GetQuery(); 
    } 


public class GenericRepository<T> : IGenericRepository<T> 
     where T : class 
    { 
     private MyApplicationEntities Currentcontext; 
     public ObjectSet<T> entitySet; 
     private List<GenericRepository<T>> _list = null; 
     private string entityName; 

     public GenericRepository(MyApplicationEntities context) 
     { 
      if (context == null) 
       throw new ArgumentNullException("context"); 
      this.Currentcontext = context; 
      this.entitySet = context.CreateObjectSet<T>(); 
      this.entityName = entitySet.Name; 
     } 

     #region READ 
     public IEnumerable<T> Query(Func<T, bool> predicate) 
     { 
      return this.entitySet.Where(predicate); 
     } 


     public T GetFirstorDefault(Func<T, bool> predicate) 
     { 
      return this.Query(predicate).FirstOrDefault(); 
     } 


     public IEnumerable<T> GetAll() 
     { 
      return this.entitySet.AsEnumerable(); 
     } 

     public T GetByKey(Func<T, bool> predicate) 
     { 
      return this.Query(predicate).FirstOrDefault(); 
     } 
     #endregion 
} 

// 클라이언트 호출 예를 들어, 대부분의 가능성이 unitOfWork.City 또는 .GetFirstOrDefault 방법 구현이 DbSet<T> 전에 필터를 적용에 열거 된 조건

var tempList = _unitofWork.RepRechargeable.Query(item => item.COMPANY_CODE == companyCode 
                  && item.DIVISION_CODE == divisionCode && !string.IsNullOrEmpty(item.PROPERTY)); 
+1

당신은 우리에게 당신의 Linq에 표시되어야를 code –

+1

코드 –

+0

은'unitWork.City'와'GetFirstorDefault' 메쏘드의 구현을 보여줍니다. – Moho

답변

0

에 대한 모든 DESC_RECHARGEABLE 행을로드합니다. 더 많은 코드를 보여 주면, 우리는 이것이 어디에서 일어나고 있는지 정확히 지적 할 수 있습니다.

3

좋아, OP에서 내 의견을 기반으로, 여기에 내 목을 걸 겠어.

Func<T, bool> predicate의 사용이 문제의 근본 원인 일 가능성이 큽니다. Func<>을 사용하면 대상 구조 (경우에 따라 query 변수)에 대해 로컬 메모리에서 코드가 실행됩니다.

Expression<Func<T, bool>> predicate을 사용하도록 메소드 서명을 변경하면이 문제가 완화되고 지연된 예외 처리 (예 : SQL Server 등에서의 처리)가 허용됩니다.

이것은 (Expression<Func<>>) 쿼리를 만들기 전에 식 트리를 만들고이 (IQueryable)을 서버에 보내기 때문입니다. 그런 다음 필터링 된 목록을 반환합니다. 반대로 Func<>을 사용하면 전체 개체 그래프가 요청되고 로컬 메모리에서 사후 처리됩니다.

저는이 기술에 대한 전문적 지식이 없지만 해결책을 제시하는 데 도움이됩니다.

빠른 비교를 보여준다 : IEnumerable을위한

  • 확장 방법은 확장 된 IQueryable 방법이 작동 Func<T>;
  • 작동 Expression<Func<T>>;

이 경우에만 IQueryable을 연기받을 것을 의미합니다 Expression<Func<T>>을 사용하여

인터페이스 :

T GetFirstorDefault(Expression<Func<T, bool>> predicate); 

구현 : 분명히

public T GetFirstorDefault(Expression<Func<T, bool>> predicate) 
{ 
    return this.Query(predicate).FirstOrDefault(); 
} 

, 다른 모든 방법이 변경 사항을 따를 것입니다,이 성공적으로 증명해야 반올림하려면 여기 문제 방법은 지금과 같을 것이다 무엇 .

이 기능이 어떻게 활용되는지 알려주세요.

[편집] - 둘 사이의 차이의 폭 넓은 윤곽주고 (웃기려는 의도 없음), 약간의 링크를 추가 :