2010-11-25 52 views
1

J'ai un référentiel générique avec la méthode suivanteLINQ IQueryable court-circuiter un paramètre de recherche vide

IQueryable<T> GetAllByFilter(Expression<Func<T, bool>> expression); 

J'essaie maintenant de fournir une fonction de recherche par l'avant, où un ou plusieurs paramètres pourraient avoir été entré ou laissé vide. J'ai des problèmes pour court-circuiter l'expression pour les paramètres vides.

Le problème peut être démontré en appelant l'exemple suivant sur le référentiel:

public IEnumerable<Foo> Search(string param) 
{ 
    var filteredFoos = _fooRepository.GetAllByFilter(
      f => string.IsNullOrEmpty(param) || f.Something == param); 

    return filteredFoos.ToList(); // throws exception 
} 

Énumération la requête avec ToList() jette un System.NullReferenceException si param est null. Je ne comprends pas cela et je ne sais pas comment le réparer, donc tous les pointeurs apprécié. Merci.

MISE À JOUR: en réponse aux commentaires ci-dessous, j'ai ajouté une vérification nulle. Mon code actuel ressemble à ceci maintenant

var test1 = _repository.GetAllByFilter(
    r => r != null && 
     (string.IsNullOrEmpty(param) 
       || (r.Field != null && r.Field.IndexOf(param.Trim()) != -1))); 

var test2 = test1.ToList(); // exception here 

Je ne vois toujours pas où le problème pourrait être.

EDIT: en réponse au commentaire, le référentiel générique GetAllByFilter code:

public IQueryable<T> GetAllByFilter(Expression<Func<T, bool>> expression) 
{ 
    return _dataContext.GetTable<T>().Where(expression); 
} 

Notez que si je lance un GetAll requête simple

public IQueryable<T> GetAll() 
{ 
    return _dataContext.GetTable<T>(); 
} 

sur la même table, pas null records sont retournés (comme prévu).

+1

qui ne marche pas droit son, êtes-vous sûr qu'il ya des occasions arent lorsque le 'f' paramètre est nul, et 'f.Something' jette l'exception? –

+0

Je ne crois pas, la requête tourne bien tant qu'une chaîne non nulle est passée en tant que param. Je ne vois pas comment f pourrait être nul? – fearofawhackplanet

+2

@fearofawhackplanet - La seule façon dont 'f' serait nul est si' _fooRepository' renvoyait un élément nul. Êtes-vous sûr que ce n'est pas le cas? – GenericTypeTea

Répondre

0

gâteau.

public IEnumerable<Foo> Search(string param) 
    { 
     Expression<Func<Foo, bool>> shortCircuit = a => true; 
     Expression<Func<Foo, bool>> normal = a => a.Something == param; 

     var filteredFoos = _fooRepository.GetAllByFilter(
      string.IsNullOrEmpty(param) ? shortCircuit : normal); 

     return filteredFoos.ToList(); // no more exception. 
    } 

Vous devez juste se rappeler, vous ne pouvez pas jeter quoi que ce soit dans ces méthodes IQueryable et les attendre à comprendre. Vous pouvez probablement rendre l'expression shortCircuit statique.

+1

très moche ... –

2

rester simple:

public IEnumerable<Foo> Search(string param) 
{ 
    if (string.IsNullOrEmpty(param)) 
    { 
     return this.fooRepository.GetAll().ToArray(); 
    } 

    return this.fooRepository.GetAllByFilter(o => o.Field.Contains(param.Trim())).ToArray(); 
} 
+0

Il n'y avait pas de méthode "GetAll()" lorsque la question a été créée. Bit naïf de supposer que c'est un projet d'un homme où vous êtes autorisé à modifier toutes les parties de l'application. –