2014-01-31 2 views
0

У меня есть метод, который ищет людей в моей базе данных. Я хотел бы реорганизовать его так, чтобы он использовал хэшеты для повышения производительности.Фильтрация HashSet в EF

Я сделал упрощенный пример ниже (который не будет компилироваться, а просто дать вам идею).

В моем примере можно использовать HashSet?

using (var context = new MyEntities()) 
{ 
    var persons = new HashSet<PERSON>(context.PERSON); 

    if(!string.IsNullOrEmpty(age)) 
    { 
     persons = persons.Where(p => p.age == age); 
    } 

    if(!string.IsNullOrEmpty(name)) 
    { 
     persons = persons.Where(p => p.name.StartsWith(name)); 
    } 
    //some similar filtering... 

    return persons.ToList(); 
} 
+0

Предупреждение! У вас закончится нехватка памяти, если таблица лиц будет слишком большой, поскольку все люди будут загружены в память. Просто дайте БД выполнить фильтрацию для вас. Если запрос выполняется медленно, проверьте ваш запрос и используйте индексы. – LostInComputer

+0

его можно использовать. вы столкнулись с какой-либо проблемой? – Rezoan

+0

@Rezoan HashSets не имеет метода Where(), так что да, я столкнулся с проблемой. – Johan

ответ

1

Как уже отмечался в комментариях, следующая строкой коды не является хорошей идеей

var persons = new HashSet<PERSON>(context.PERSON); 

, потому что он будет тянуть все данные из PERSONDbSet и вставить его в person объект ,

Ваш код максимально оптимизирован без накладных расходов на чтение всех данных в HashSet.

Я предлагаю вам создать объект IQueryable, который будет запускать соответствующий специально подобранный Sql для фильтрации ваших данных. Ничего не будет считано из базы данных до момента, когда вы звоните ToList()

var persons = context.PERSON.AsQueryable(); 

if(!string.IsNullOrEmpty(age)) 
{ 
    persons = persons.Where(p => p.age == age); 
} 

if(!string.IsNullOrEmpty(name)) 
{ 
    persons = persons.Where(p => p.name.StartsWith(name)); 
} 
//some similar filtering... 

return persons.ToList(); 
+1

да, это то, о чем я говорю. – Rezoan

+0

Есть ли разница между '.AsQueryable()' и явным определением лиц как 'IQueriable '? Что произойдет, если моя лямбда не может быть переведена на SQL? – Johan

+0

@ Johan нет никакой разницы между двумя - 'AsQueryable' просто означает, что вы можете использовать' var person'. Если у вас есть фильтры, которые нельзя перевести на Sql, вам придется применять эти фильтры * после * вызова toList() '. Вам нужно будет построить несколько тестов, чтобы решить, будет ли «HashSet» полезен для этого, но я бы предположил, что это, вероятно, не стоит. – qujck

Смежные вопросы