2009-07-11 14 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

他のすべてが非null許容値型であるように、NULLにすることができ、その関数に渡された値のみが、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

null可能なパラメータを持つ質問が更新されました –