2009-07-11 127 views
0

有沒有什麼辦法可以重構這段代碼,以便它可以省略不必要的WHEREs和JOINs,如果傳遞給函數的值爲null(如果所有參數都傳入,此代碼現在工作得很好)? 「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

更新的問題有可爲空的參數 – 2009-07-11 03:35:51