2010-10-18 4 views
1

Je dois obtenir la liste des noms commençant par des caractères spéciaux ou des nombres dans la requête linq to sql pour mon application asp.net mvc (C#).obtenir les noms commence par des nombres ou des caractères spéciaux dans linq à sql

J'ai essayé comme celui-ci (qui peut ne pas être efficace):

public List<User> GetUsersStartingWithNonCharacter() 
{ 
    List<User> _dbUsers = this.GetAllUsers(); 
    return _dbUsers.Where(p => ((p.FirstName != null && p.FirstName != string.Empty && !char.IsLetter(p.FirstName.ToLower()[0])) || (p.FirstName == null || p.FirstName == string.Empty))).ToList(); 
} 

public List<Users> GetAllUsers() 
{ 
    return (from u in _context.pu_Users 
      where !u.Is_Deleted 
      select new User 
      { 
       UserId = u.User_Id, 
       Email = u.Email_Address, 
       FirstName = u.First_Name, 
       LastName = u.Last_Name 
      }).ToList(); 
} 

Quelqu'un peut-il suggérer la manière la plus efficace de le faire dans LINQ to SQL?

+0

Vous devez tracer/profiler votre base de données et voir à quoi ressemble la requête du côté sql. Ensuite, vous pouvez décider si c'est efficace ou non. –

+0

En dehors des chiffres, ce qui rend un caractère "spécial" à cette affaire. Un gros problème d'efficacité est de faire correspondre les caractères correctement, mais le moyen le plus efficace dépend de ce que signifie "spécial". –

Répondre

1

Comment savez-vous si ce n'est pas déjà efficace? Utilisez un peu d'outil de profileur, comme SQL Server Profiler si vous utilisez MSSQL, de cette façon vous pouvez tracer votre appel contre la base de données et voir le SQL réel. Bien sûr, vous pouvez seulement déboguer le code pour voir le SQL généré, mais c'est plus facile avec un outil de profilage et vous verrez combien de temps prend la requête.

EDIT: Je vois une partie dans la façon dont vous pouvez le rendre plus efficace:

public List<User> GetUsersStartingWithNonCharacter() 
{ 
    List<User> _dbUsers = this.GetAllUsers(); 
    return _dbUsers.Where(p => ((p.FirstName != null && p.FirstName != string.Empty && !char.IsLetter(p.FirstName.ToLower()[0])) || (p.FirstName == null || p.FirstName == string.Empty))).ToList(); 
} 

public IQueryable<Users> GetAllUsers() 
{ 
    return from u in _context.pu_Users 
      where !u.Is_Deleted 
      select new User 
      { 
       UserId = u.User_Id, 
       Email = u.Email_Address, 
       FirstName = u.First_Name, 
       LastName = u.Last_Name 
      }; 
} 

Changer votre GetAllUsers retourner IQueryable retardera la requête à exécuter jusqu'à ce que vous avez appliqué vos filtres. Cela pourrait affecter certains autres aspects de votre conception, mais vous devriez le considérer puisque cette modification pourrait faire fonctionner votre clause where dans la base de données plutôt que dans le code, ce qui réduirait le trafic de données entre votre application et votre base de données. Encore une fois, utilisez un profiler pour voir la différence :).

+0

+1 pour l'édition. Sauf que sa condition "vérifier le premier caractère" attirera toujours toutes les lignes. –

+0

Je suppose que ce sera le cas, mais c'est un début :). Comme nous l'avons tous les deux déclaré, il doit utiliser le profileur et continuer à partir de là. –

0

Je vais utiliser Regular Expression dans ce scenerio

Voici mon exemple de code

return _dbUsers.Where(p=>p.FirstName!=String.Empty) 
       . Where(p => Regex.Match(p.Firstname[0].ToString(), "[a-zA-Z]").Success).ToList(); 
0

Je soupçonne que toutes les lignes seront récupérées et filted dans votre application en raison de la condition:

char.IsLetter(p.FirstName.ToLower()[0]) 

(L'utilisation d'une expression régulière comme suggéré dans une autre réponse entraîne également toutes les lignes et les filtre sur le client.)

Il est possible de vérifier les caractères d'une chaîne avec la fonction PATINDEX, mais il semble qu'elle soit uniquement disponible pour LINQ via l'infrastructure Entity.

Vous pouvez écrire une procédure stockée en utilisant PATINDEX directement pour vérifier le premier caractère pour optimiser votre requête. Des exemples de requêtes peuvent être trouvés au http://www.databasejournal.com/features/mssql/article.php/3071531/Using-SQL-Servers-CHARINDEX-and-PATINDEX.htm.

Parfois, LINQ to whatever ne donnera pas la solution la plus optimisée, mais c'est juste la vie. Dans la plupart des cas, il donnera un code plus clair, mais des cas particuliers pourraient nécessiter des contournements afin d'utiliser des opérateurs spéciaux du système sous-jacent.

Questions connexes