J'ai le code suivant:
return this.ObjectContext.BranchCostDetails.Where(
b => b.TarrifId == tariffId && b.Diameter == diameter
|| (b.TarrifId==tariffId && !string.IsNullOrWhiteSpace(b.Diameter))
|| (!b.TarrifId.HasValue) && b.Diameter==diameter);
Et j'obtiens cette erreur lorsque j'essaye d'exécuter le code:
LINQ to Entities ne reconnaît pas la méthode 'Boolean IsNullOrWhiteSpace (System.String)', et cette méthode ne peut pas être traduite en une expression de magasin. "
Comment puis-je résoudre ce problème et écrire du code mieux que cela?
List<string> my = new List<string>(); var i = from m in my where !string.IsNullOrWhiteSpace(m) select m;
Dans ce cas, il est important de faire la distinction entre
IQueryable<T>
etIEnumerable<T>
. En bref, ilIQueryable<T>
est traité par un fournisseur LINQ pour fournir une requête optimisée. Lors de cette transformation, toutes les instructions C # ne sont pas prises en charge, car il n'est pas possible de les traduire en une requête spécifique au back-end (par exemple SQL) ou parce que l'implémenteur n'a pas prévu la nécessité de l'instruction.En revanche
IEnumerable<T>
est exécuté contre les objets concrets et, par conséquent, ne sera pas transformé. Ainsi, il est assez courant que les constructions, qui sont utilisables avecIEnumerable<T>
, ne puissent pas être utilisées avecIQueryable<T>
et que cellesIQueryables<T>
soutenues par différents fournisseurs LINQ ne prennent pas en charge le même ensemble de fonctions.Cependant, il existe quelques solutions de contournement (comme la réponse de Phil ), qui modifient la requête. De plus, comme approche plus générale, il est possible de revenir à un
IEnumerable<T>
avant de continuer avec la spécification de la requête. Ceci, cependant, peut avoir un impact sur les performances - en particulier lors de son utilisation sur des restrictions (par exemple, clauses where). En revanche, lorsqu'il s'agit de transformations, l'impact sur les performances est beaucoup plus faible, parfois même inexistant, en fonction de votre requête.Ainsi, le code ci-dessus pourrait également être réécrit comme ceci:
REMARQUE: Ce code aura un impact sur les performances supérieur à la réponse de Phil . Cependant, cela montre le principe.
la source
Utilisez un visiteur d'expression pour détecter les références à string.IsNullOrWhiteSpace et les décomposer en une expression plus simple
(x == null || x.Trim() == string.Empty)
.Vous trouverez donc ci-dessous un visiteur étendu et une méthode d'extension pour l'utiliser. Il ne nécessite aucune configuration spéciale à utiliser, appelez simplement WhereEx au lieu de Where.
Donc, si vous l'exécutez,
myqueryable.WhereEx(c=> !c.Name.IsNullOrWhiteSpace())
il sera converti en!(c.Name == null || x.Trim() == "")
avant d'être transmis à quoi que ce soit (linq en sql / entités) et converti en sql.la source
Vous pouvez également l'utiliser pour vérifier les espaces:
la source
lèvera une exception si
b.Diameter
c'estnull
.Si vous souhaitez toujours utiliser votre relevé, mieux vaut utiliser cette vérification
la source