Linq 2 Sql Динамические запросы - PullRequest
0 голосов
/ 11 июля 2009

Есть ли способ реорганизовать этот код, чтобы он мог пропустить ненужные 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
                      };
}

Ответы [ 2 ]

2 голосов
/ 11 июля 2009

Я делаю предположение, что если широта или долгота не указаны, вы не рассчитываете расстояние (я бы, вероятно, инкапсулировал оба в класс и передавал его вместо прохождения отдельно, чтобы избежать путаницы). Если одно или другое не указано, для результата поиска используется расстояние по умолчанию.

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 голос
/ 11 июля 2009

Для начала, единственное значение, передаваемое в эту функцию, которое может иметь значение 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
                  };
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...