169 votes

String.IsNullOrWhiteSpace dans LINQ Expression

J’ai le code suivant :

Et j’obtiens cette erreur lorsque j’essaie d’exécuter le code :

LINQ to Entities ne reconnaît pas la méthode du « Boolean IsNullOrWhiteSpace(System.String) », et cette méthode ne peut pas se traduire par une expression de magasin. »

Comment puis-je résoudre ce problème et écrire du code mieux que cela ?

289voto

Phil Points 19299

Vous devez remplacer

 !string.IsNullOrWhiteSpace(b.Diameter)
 

avec

 !(b.Diameter == null || b.Diameter.Trim() == string.Empty)
 

Pour Linq to Entities, cela se traduit en:

 DECLARE @p0 VarChar(1000) = ''
...
WHERE NOT (([t0].[Diameter] IS NULL) OR (LTRIM(RTRIM([t0].[Diameter])) = @p0))
 

et pour Linq to SQL presque mais pas tout à fait pareil

 DECLARE @p0 NVarChar(1000) = ''
...
WHERE NOT (LTRIM(RTRIM([t0].[TypeName])) = @p0)
 

21voto

AxelEckenberger Points 9546

Dans ce cas, il est important de faire la distinction entre IQueryable<T> et IEnumerable<T>. En court - IQueryable<T> ist traitées par un fournisseur LINQ pour offrir une optimisation de requête. Au cours de cette transformation, non tous les C# déclarations sont pris en charge, qu'elle soit-il pas possible de les traduire en une interface de requête spécifique (par exemple, SQL) ou parce que le réalisateur n'a pas entrevoir la nécessité de l'instruction.

Dans le contrat d' IEnumerable<T> est exécutée sur les objets concrets et, par conséquent, ne sera pas transformé. Donc, il est assez fréquent que des constructions, qui sont useablewith IEnumerable<T>, ne peut pas être utilisé avec IQueryable<T> et aussi qu' IQueryables<T> soutenu par différents fournisseurs LINQ ne prennent pas en charge le même ensemble de fonctions.

Cependant, il existe quelques solutions de contournement (comme Phil de réponse), de modifier la requête. Aussi, une approche plus générale, il est possible de revenir à une IEnumerable<T> avant de continuer avec la spécification de la requête. Ceci, cependant, peut avoir un gain de performance - en particulier lors de l'utilisation sur les restrictions (par exemple, les clauses where). En revanche, lorsque vous traitez avec les transformations de l'impact sur les performances est beaucoup plus petit, parfois même inexistante, suivant votre requête.

Donc le code ci-dessus peut également être réécrit comme ceci:

return this.ObjectContext.BranchCostDetails
    .AsEnumerable()
    .Where(
        b => b.TarrifId == tariffId && b.Diameter == diameter
        || (b.TarrifId==tariffId && !string.IsNullOrWhiteSpace(b.Diameter))
        ||(!b.TarrifId.HasValue) && b.Diameter==diameter
    );

REMARQUE: Sat code aura un meilleur impact sur les performances de Phil réponse. Cependant, il montre le principe.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X