Convertir un int en String avec Linq to Entity – Utilisation de Entity SQL - LINQ to Entities does not recognize the method 'System.String ToString()' method
Dans certains cas, on a besoin de faire une recherche dans la base afin de savoir si un nombre contient un certain fragment. Par exemple si vous avez une table contenant des grands entiers, vous aimerez pouvoir rechercher toutes les lignes dont le nombre possède 23 (123, 242354, …)
La requête SQL est simple :
SELECT *
FROM dbo.Person
WHERE Num LIKE '%12%';
Avec Linq To Entity, la requête devrait ressembler à :
IEnumerable<Person> persons = entities.Person
.Where(p => p.Num.ToString().Contains("12"));
Afin de reproduire le comportement du Like, on est obligé de convertir notre entier en String et d’utiliser la méthode Contains. Si l’on exécute ce code, alors on obtient une exception :
LINQ to Entities does not recognize the method 'System.String ToString()' method, and this method cannot be translated into a store expression.
Malheureusement, je n’ai pas trouvé de solution pour convertir un entier en String avec Linq To Entities. Une des solutions est de convertir notre IQueryable en IEnumerable, c’est à dire de récupérer l’ensemble des éléments coté .net puis de faire le where en Linq to Object, niveau performance ce n’est pas jouable !
L’autre solution est d’utiliser du entity SQL :
IEnumerable<Person> persons = entities.Person
.Where("cast(it.Num as System.String) like '%' + @nb + '%'",
new ObjectParameter("nb", 10.ToString()));
Ainsi, la requête générée par le moteur Linq To Entities est correctement traduite en SQL.
Je trouve étonnant que l’équipe de Linq To Entities, ne propose pas de solution simple pour résoudre ce problème. Lors du parsing de l’expression, il me semble simple de traduire int.ToString en cast( … as System.String), cela pose peut être quelques problèmes au niveau des cultures, mais je ne pense pas que cela soit bloquant.
Je n’ai pas testé avec EF4 (Entity Framework de .net 4), quelqu’un sait si ce cas sera plus simple avec EF4 ? une autre solution ?