2009-07-11 6 views
0

함수에 전달 된 값이 null 인 경우 불필요한 WHERE 및 JOIN을 생략 할 수 있도록이 코드를 리팩터링 할 수있는 방법이 있습니까? (이 코드는 모든 매개 변수가 전달되면 올바르게 작동합니다)? "SearchItems"및 "ItemDistance"함수는 전체 텍스트 검색 및 거리 계산을 각각 수행하기위한 테이블 수준 함수입니다. 모든 다른 비 - 널 값의 종류만큼 시동기Linq 2 Sql 동적 쿼리

public IQueryable<ItemSearchResult> Search(string keywords, int? category, float? latitude, float? longitude) 
{ 
    return from item in _db.Items 
      join searchItems in _db.SearchItems(keywords) 
       on item.ItemId equals searchItems.ItemId 
      join itemDistance in _db.ItemDistance(latitude.Value, longitude.Value) 
       on item.ItemId equals itemDistance.ItemId 
      where item.Category == category.Value 
      select new ItemSearchResult() 
         { 
          Item = item, 
          Distance = itemDistance.Distance 
         }; 
} 

답변

2

내가 위도 나 경도의 하나가 제공되지 않으면, 당신은 거리를 계산하지 않는다는 가정을 만들고있어 내가 좋겠 아마도 두 클래스를 모두 캡슐화하고 혼동을 피하기 위해 별도로 전달하는 대신 전달하십시오. 둘 중 하나를 제공하지 않으면 기본 거리가 검색 결과에 사용됩니다.

public IQueryable<ItemSearchResult> Search(string keywords, int? category, float? latitude, float? longitude) 
{ 
    IEnumerable<ItemSearchResult> result = null; 
    var query = _db.Items.AsEnumerable(); 
    if (category.HasValue) 
    { 
     query = query.Where(i => i.Category == category.Value); 
    } 
    if (!string.IsNullOrEmpty(keywords)) 
    { 
     query = query.Where(i => _db.SearchItems(keywords) 
            .Any(s => s.ItemId == i.ItemId)); 
    } 
    if (latitude.HasValue && longitude.HasValue) 
    { 
     result = from item in query 
       join distance in _db.ItemDistance(latitude.Value, longitude.Value) 
        on item.ItemId equals distance.ItemId 
       select new ItemSearchResult 
         { 
          Item = item, 
          Distance = distance.Distance 
         }; 
    } 
    else 
    { 
     result = query.Select(i => new ItemSearchResult { Item = i }); 
    } 

    return result != null 
       ? result.AsQueryable() 
       : new List<ItemSearchResult>().AsQueryable(); 
} 
1

는 널이 될 수있는 함수로 전달되는 유일한 값은 keywords이다. 그래서 나는 그것을 (당신이 그것을 필요로한다면 다른 사람들도 비슷하게 대우받을 수있다) 고려할 것입니다. 사용하지 않는

그냥 처음에 조인 (

return from item in _db.Items 
     where keywords == null || _db.SearchItems(keywords).Select(si => si.ItemId).Contains(item.ItemId) && 
     ...  
     where item.Category == category 
     select new ItemSearchResult() 
        { 
         Item = item, 
         Distance = itemDistance.Distance 
        }; 
+0

nullable 매개 변수가있는 질문이 업데이트되었습니다. –