2010-07-29 23 views
135

Este código es sensible a mayúsculas y minúsculas, ¿cómo hacerlo insensible a mayúsculas y minúsculas?LINQ contiene insensible a mayúsculas y minúsculas

public IQueryable<FACILITY_ITEM> GetFacilityItemRootByDescription(string description) 
{ 
    return this.ObjectContext.FACILITY_ITEM.Where(fi => fi.DESCRIPTION.Contains(description)); 
} 
+3

respuesta de Sjoerd debe marcarse como la correcta – fubo

Respuesta

207
fi => fi.DESCRIPTION.ToLower().Contains(description.ToLower()) 
+0

Gracias Nealv, ahora se está trabajando. –

+1

podría haber una solución más elegante, pero esto es lógico y funciona de todos modos. Buscaré la solución elegante más tarde – Nealv

+39

Como [Jon Skeet] (http: // stackoverflow.com/users/22656/jon-skeet) comentó sobre una [pregunta relacionada] (http://stackoverflow.com/a/444813/161052), este método no pasará la [Prueba de Turquía] (http: // www) .moserware.com/2008/02/does-your-code-pass-turkey-test.html). – JYelton

57

Suponiendo que estamos trabajando con las cadenas aquí, aquí hay otra solución "elegante" usando IndexOf().

public IQueryable<FACILITY_ITEM> GetFacilityItemRootByDescription(string description) 
{ 
    return this.ObjectContext.FACILITY_ITEM 
     .Where(fi => fi.DESCRIPTION 
         .IndexOf(description, StringComparison.OrdinalIgnoreCase) != -1); 
} 
+0

s/elegant/magic :) – Earlz

+5

Agradable. Sin embargo, para mis propios fines, esto no funciona para LINQ to Entities. Buena solución para LINQ to Objects. –

+2

Pero funciona con Linq2SQL –

100

Si la consulta LINQ se ejecuta en el contexto de la base, una llamada a Contains() está asignada al operador LIKE:

.Where(a => a.Field.Contains("hello")) convierte Field LIKE '%hello%'. El operador LIKE distingue entre mayúsculas y minúsculas por defecto, pero puede cambiarse por changing the collation of the column.

Si la consulta LINQ se ejecuta en contexto .NET, puede usar IndexOf(), pero ese método no es compatible con LINQ to SQL.

LINQ to SQL does not support methods que toma un CultureInfo como parámetro, probablemente porque no puede garantizar que el servidor SQL maneje culturas de la misma manera que .NET. Esto no es completamente cierto, porque hace admite StartsWith(string, StringComparison).

Sin embargo, no parece ser compatible con un método que evalúa LIKE en LINQ to SQL, y con una comparación insensible a mayúsculas/minúsculas en .NET, lo que hace imposible hacer insensible a mayúsculas/minúsculas() de manera consistente.

+0

Just FYI EF 4.3 no es compatible con StartsWith. Obtengo: LINQ to Entities no reconoce el método 'Boolean StartsWith (System.String, System.StringComparison)' – nakhli

+0

StartWith se convierte en LIKE 'hello%'? –

+0

clicdata link is dead. –

1
public static bool Contains(this string input, string findMe, StringComparison comparisonType) 
{ 
    return String.IsNullOrWhiteSpace(input) ? false : input.IndexOf(findMe, comparisonType) > -1; 
} 
+2

¿podemos usar métodos de extensión personalizados en consultas de linq? Estás seguro ? –

9

La respuesta aceptada aquí no menciona un hecho que si usted tiene una cadena nula ToLower() lanzará una excepción. La manera más segura sería la de hacer:

fi => (fi.DESCRIPTION ?? string.Empty).ToLower().Contains((description ?? string.Empty).ToLower()) 
+0

No se puede generar una excepción en una consulta traducida a SQL –

+0

@AlexZhukovskiy ¿Cómo es eso relevante para este problema? Si fi.DESCRIPTION es nulo o la descripción es nula, recibirá una excepción de referencia nula C#. No importa a qué se convierta la consulta LINQ en el lado de SQL. Aquí está la prueba: https://dotnetfiddle.net/5pZ1dY – Marko

+0

Porque esta consulta fallará la traducción a SQL porque no es compatible con el operador coaleshing nulo. Y es probable que query base de datos en lugar de cargar todas las entradas para utilizar coaleshing nulo en el lado del cliente. Entonces, si lo usa, está bien en el lado del cliente pero falla en DB, de lo contrario está bien con DB y no le importa nullref en el lado del cliente porque no sucederá porque C# no ejecuta esta consulta y doesn De hecho, lees objetos nulos. –

2

IndexOf funciona mejor en este caso

return this 
.ObjectContext 
.FACILITY_ITEM 
.Where(fi => fi.DESCRIPTION.IndexOf(description, StringComparison.OrdinalIgnoreCase)>=0); 
0

Utilice el método Enumerable.Contains(IEnumerable, TSource, IEqualityComparer), usando uno de los comparadores StringComparer .___ ignoreCase (O ordinal, InvariantCulture o CurrentCulture).

public IQueryable<FACILITY_ITEM> GetFacilityItemRootByDescription(string description) 
{ 
    return this.ObjectContext.FACILITY_ITEM.Where(
     fi => fi.DESCRIPTION.Contains(description, StringComparer.OrdinalIgnoreCase) 
    ); 
} 
+0

Esto no está bien, en realidad está invocando el LINQ Contiene en 'IEnumerable ' de DESCRIPTION. Este código ni siquiera compilará porque StringComparer no es un Comparador para char. Esta respuesta debe ser eliminada. –

2

Uso de C# 6.0 (que permite la expresión funciones de cuerpo y la propagación null), para LINQ a objetos, se puede hacer en una sola línea como este (también la comprobación de null):

public static bool ContainsInsensitive(this string str, string value) => str?.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0; 
+0

No funciona porque ContainsInsensitive no es un comando de tienda – Sven

+0

@Sven - sí, funciona solo para LINQ to Objects. He arreglado mi respuesta. Gracias. – Alexei

+0

Hola Alexei, sí ahora. Gracias. – Sven

3

puede utilizar string.Compare

lst.Where(x => string.Compare(x,"valueToCompare",StringComparison.InvariantCultureIgnoreCase)==0); 

si sólo quiere comprobar contiene continuación, utilizar "Cualquier"

lst.Any(x => string.Compare(x,"valueToCompare",StringComparison.InvariantCultureIgnoreCase)==0) 
-1

Uso String.Equals Método

public IQueryable<FACILITY_ITEM> GetFacilityItemRootByDescription(string description) 
{ 
    return this.ObjectContext.FACILITY_ITEM 
      .Where(fi => fi.DESCRIPTION 
      .Equals(description, StringComparison.OrdinalIgnoreCase)); 
} 
Cuestiones relacionadas