2012-01-27 1 views
2

J'essaie d'implémenter une recherche de texte pour les tables de base de données. J'ai un dépôt générique et je ne veux pas vraiment avoir à en créer pour tous les modèles que je pourrais vouloir exposer car il y en a beaucoup dans la base de données.Recherche de texte sur le type générique dans Entity Framework

Donc le code que je vais avoir du mal à se présente comme suit:

var props = typeof(T).GetProperties() 
    .Where(p => p.PropertyType == typeof(string)); 

IEnumerable<T> searched = null; 
if (!string.IsNullOrWhiteSpace(searchTerm)) 
    searched = sorted.Where(c => props 
     .Select(p => (string)p.GetValue(c, null)) 
     .Select(v => v.Contains(searchTerm)) 
     .Contains(true)); 

Je cette alimentation une collection de ce PropertyInfo obtenu par un peu de réflexion. Peut-être pas une idée de haute performance mais je n'ai pas encore trouvé de meilleure solution. Il peut donc s'agir de toutes les propriétés de type string (recherche dans toutes les chaînes de la table) ou de certaines propriétés du modèle ayant un attribut Searchable personnalisé.

L'exception d'exécution je reçois est:

NotSupportedException: Impossible de créer une valeur constante de type 'System.Reflection.PropertyInfo'. Seuls les types primitifs ('tels que Int32, String et Guid') sont pris en charge dans ce contexte.

Je peux voir que j'utilise la réflexion, mais je ne sais pas exactement ce qui cause l'exception ici. Si quelqu'un pouvait le signaler, ce serait très apprécié, mais si quelqu'un pouvait suggérer une meilleure façon de le faire, ce serait formidable. Merci d'avance!

Répondre

1

Le problème est que lorsque la requête LINQ est exécutée, elle tente de construire une requête SQL à effectuer sur la base de données. Le message d'exception indique que seuls les types primitifs peuvent être utilisés dans la requête LINQ car ce sont les seuls types qui peuvent être convertis avec succès dans une requête SQL.

En espérant résoudre votre problème, vous devez simplement vous assurer que la requête SQL de la base de données s'exécute avant d'étendre la requête LINQ en utilisant des types non-primitifs.

Je suppose que la variable sorted dans votre extrait de code est une requête LINQ, appelez donc sorted.AsEnumerable() pour exécuter la requête SQL sur la base de données, puis vous pouvez exécuter la fonctionnalité de recherche.

searched = sorted.AsEnumerable() 
       .Where(c => props.Select(p => (string)p.GetValue(c, null)) 
            .Any(v => v.Contains(searchTerm))); 
+0

Merci pour votre réponse. Vous avez raison sur le problème mais la solution n'est pas tout à fait ce que je cherche. La réflexion dans la clause where est dans le but de filtrer les colonnes dans la base de données. Ce dont j'ai vraiment besoin, c'est d'une alternative à la réflexion pour le faire. Up a voté tout de même. :) –

Questions connexes