En este caso es importante distinguir entre IQueryable<T>
y IEnumerable<T>
. En resumen, IQueryable<T>
es procesado por un proveedor de LINQ para entregar una consulta optimizada. Durante esta transformación, no se admiten todas las declaraciones de C #, ya que no es posible traducirlas a una consulta específica de fondo (por ejemplo, SQL) o porque el implementador no previó la necesidad de la declaración.
Por el contrario, IEnumerable<T>
se ejecuta contra los objetos concretos y, por lo tanto, no se transformará. Por lo tanto, es bastante común que las construcciones, que son utilizables con IEnumerable<T>
, no se puedan usar IQueryable<T>
y también que IQueryables<T>
respaldadas por diferentes proveedores de LINQ no admitan el mismo conjunto de funciones.
Sin embargo, hay algunas soluciones (como la respuesta de Phil ), que modifican la consulta. Además, como un enfoque más general, es posible volver a IEnumerable<T>
antes de continuar con la especificación de la consulta. Esto, sin embargo, podría tener un impacto en el rendimiento, especialmente cuando se usa en restricciones (por ejemplo, cláusulas where). Por el contrario, cuando se trata de transformaciones, el impacto en el rendimiento es mucho menor, a veces incluso inexistente, dependiendo de su consulta.
Entonces, el código anterior también podría reescribirse así:
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
);
NOTA: Este código tendrá un mayor impacto en el rendimiento que la respuesta de Phil . Sin embargo, muestra el principio.
List<string> my = new List<string>(); var i = from m in my where !string.IsNullOrWhiteSpace(m) select m;