2012-07-13 2 views
0

현재 MVF 검색보기/페이지에서 여러 텍스트 상자에 대한 사용자 입력을 기반으로 EF CodeFirst와 저장소 패턴을 사용하여 검색하려면 다음과 같이하십시오.EF를 사용하여 검색하는 방법 CodeFirst

public PagedList<Entity1> PlayerUserSearch(Entity1SearchParameters searchParameters, int? pageSize, int? startEntity, Func<Entity1, object> sortOrder, bool sortDesc) 
    { 
     IQueryable<Entity1> query = from entities in this.DataContext.Entity1s.Include("Entity2List") 
            where entities.Entity2List.Any() 
            select entities; 

     if (searchParameters.Entity2PrimaryKeyId.HasValue) 
      query = query.Where(e => e.Id == searchParameters.Entity2PrimaryKeyId.Value); 

     if (searchParameters.HasStats.HasValue) 
     { 
      if (searchParameters.HasStats.Value) 
       query = query.Where(u => u.Entity2List.Any(e => e.Stat != null)); 
      else 
       query = query.Where(u => u.Entity2List.Any(e => e.Stat == null)); 
     } 

     if (searchParameters.Entity2OtherField.HasValue) 
      query = query.Where(u => u.Entity2List.Any(e => e.Event.Entity2OtherField == searchParameters.Entity2OtherField)); 

     if (searchParameters.Entity2OtherField2.HasValue) 
      query = query.Where(u => u.Entity2List.Any(e => e.Event.Entity2OtherField2 == searchParameters.Entity2OtherField2)); 

     if (searchParameters.Active.HasValue) 
      query = query.Where(e => e.Active == searchParameters.Active.Value); 

     return this.GetPageByStartEntity(pageSize.Value, startEntity.Value, query, sortOrder, sortDesc); 
    } 

이 문제는 특정 필드에 대해 Entity1 (Entity2)의 하위를 검사하는 다른 위치에 추가 할 때마다 생성 된 SQL 문에 새로운 "AND EXISTS"절이 필요하다는 것입니다. 그것은 Entity2를 Entity2 테이블 전체를 검사하는 것입니다. 쿼리의 Entity에 대해 하나의 EXISTS를 수행하고 쿼리 (예 : EntityOtherField1 및 EntityOtherField2)에 연결하는 모든 필드를 검사하는 것이 아닙니다. 사용자 입력을 기반으로 검색을 수행하는 더 좋은 방법을 찾지 못했습니다 (검색 매개 변수에 추가) 입력을 지속적으로 확인한 다음 현재 쿼리에 대한 새 위치를 지정합니다. 누구든지이 일을하는 더 좋은 방법이 있는지 말해 줄 수 있습니까? 감사!

답변

0

당신이 찾고있는 것이 사양 패턴을 사용하고 있다고 생각합니다.

var spec = new specification<Entity2>(s => true); 
if (searchParameters.HasStats.Value) 
{ 
    spec = spec.And(e => e.Stat != null); 
} 

if (searchParameters.Entity2OtherField2.HasValue) 
{ 
     spec = spec.And(e => e.Event.Entity2OtherField2 == searchParameters.Entity2OtherField2); 
} 

query = query.Where(u => u.Entity2List.Any(spec)); 

이 아니면 당신이 필터 로직을 분리 spec.IsStatisfiedBy 방법을 사용하여 더 표준 만들 수 있다고 생각합니다. Entity Framework에서 리포지토리/사양 구현을위한 좋은 프레임 워크는 here입니다.

+0

필자가 더 큰 문제는 Entity2가 동일한 엔티티/테이블에 Any (존재)를 갖는 충돌을 반환하도록 Include를 사용한다는 것입니다. ... 그래서 내가 Entity2 하위 목록에있는 Any를 사용하여 찾고자하는 것을 제한하더라도 Include를 사용하면 해당 테이블에 대한 조인이 계속 발생하여 해당 테이블의 모든 레코드에 조인됩니다. 그것을 원한다. Any를 사용하는 대신 존재하는 대신 현재 절에 매개 변수 검사를 추가하는 대신에 Any를 사용하는 대신에이를 수행 할 수 있도록 어떻게 얻을 수 있습니까? – user1368182

관련 문제