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