有没有办法重构这段代码,以便在传递给函数的值为null时可省略不必要的WHERE和JOIN(如果传入所有参数,此代码现在可以正常工作)? “SearchItems”和“ItemDistance”函数分别是用于执行全文搜索和距离计算的表级函数。
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
};
}
答案 0 :(得分: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 :(得分:1)
对于初学者,传递给该函数的唯一可以为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
};