繁体   English   中英

Linq 2 SQL动态查询

[英]Linq 2 Sql Dynamic Queries

有什么方法可以重构此代码,以便在传递给函数的值为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
                      };
}

我假设如果未提供纬度或经度,则不计算距离(我可能会将两者封装到一个类中,然后通过传递而不是分别传递以避免混淆)。 如果未提供任何一个,则将默认距离用于搜索结果。

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();
}

对于初学者来说,传递给该函数的唯一可以为null的值是keywords ,因为其他所有值都是不可为null的值类型。 因此,我将仅考虑(如果您需要,其他人也可以被类似地对待)。

只是首先不要使用联接:

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
                  };

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM