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.