Tengo el siguiente código:
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);
Y obtengo este error cuando intento ejecutar el código:
LINQ to Entities no reconoce el método 'Boolean IsNullOrWhiteSpace (System.String)', y este método no se puede traducir a una expresión de tienda ".
¿Cómo puedo resolver este problema y escribir código mejor que esto?
List<string> my = new List<string>(); var i = from m in my where !string.IsNullOrWhiteSpace(m) select m;
En este caso es importante distinguir entre
IQueryable<T>
yIEnumerable<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 conIEnumerable<T>
, no se puedan usarIQueryable<T>
y también queIQueryables<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í:
NOTA: Este código tendrá un mayor impacto en el rendimiento que la respuesta de Phil . Sin embargo, muestra el principio.
fuente
Use un visitante de expresión para detectar referencias a string.IsNullOrWhiteSpace y desglosarlas en una expresión más simple
(x == null || x.Trim() == string.Empty)
.A continuación, se muestra un visitante extendido y un método de extensión para utilizarlo. No requiere una configuración especial para usar, simplemente llame a WhereEx en lugar de Where.
Entonces, si ejecuta
myqueryable.WhereEx(c=> !c.Name.IsNullOrWhiteSpace())
, se convertirá a!(c.Name == null || x.Trim() == "")
antes de pasar a lo que sea (linq a sql / entidades) y se convertirá a sql.fuente
También puede usar esto para verificar los espacios en blanco:
fuente
lanzará una excepción si
b.Diameter
es asínull
.Si aún desea usar su estado de cuenta, mejor use este cheque
fuente