visual tutorial new net for examples .net sql vb.net linq linq-to-sql

.net - new - tutorial de linq vb net



Comparación de cadenas insensibles a mayúsculas/minúsculas en LINQ-to-SQL (8)

Como dices, hay algunas diferencias importantes entre ToUpper y ToLower, y solo una es confiable cuando intentas hacer verificaciones de igualdad que no distinguen entre mayúsculas y minúsculas.

Idealmente, la mejor manera de hacer una verificación de igualdad insensible a mayúsculas y minúsculas es:

String.Equals(row.Name, "test", StringComparison.OrdinalIgnoreCase)

Tenga en cuenta el Ordinal IgnoreCase para que sea seguro. Pero exactamente el tipo de control (sensible) de caso (en) que utiliza depende de cuáles sean sus propósitos. Pero, en general, usa Igual para verificaciones de igualdad y Compare cuando ordena, y luego elija el StringComparison correcto para el trabajo.

Michael Kaplan (una autoridad reconocida en cultura y manejo de personajes como este) tiene publicaciones relevantes sobre ToUpper vs. ToLower:

Él dice "String.ToUpper - Use ToUpper en lugar de ToLower, y especifique InvariantCulture para poder recoger las reglas de la carcasa del sistema operativo "

He leído que no es prudente usar ToUpper y ToLower para realizar comparaciones de cadenas que no distinguen entre mayúsculas y minúsculas, pero no veo otra alternativa cuando se trata de LINQ-to-SQL. Los argumentos ignoreCase y CompareOptions de String.Compare son ignorados por LINQ-to-SQL (si está utilizando una base de datos de mayúsculas y minúsculas, obtendrá una comparación sensible a mayúsculas de minúsculas incluso si solicita una comparación que no distinga entre mayúsculas y minúsculas). ¿ToLower o ToUpper son la mejor opción aquí? ¿Es uno mejor que el otro? Creí leer en alguna parte que ToUpper era mejor, pero no sé si eso se aplica aquí. (Estoy haciendo muchas revisiones de código y todos están usando ToLower).

Dim s = From row In context.Table Where String.Compare(row.Name, "test", StringComparison.InvariantCultureIgnoreCase) = 0

Esto se traduce en una consulta SQL que simplemente compara row.Name con "prueba" y no devuelve "Test" y "TEST" en una base de datos sensible a mayúsculas y minúsculas.


El siguiente enfoque de dos etapas me funciona (VS2010, ASP.NET MVC3, SQL Server 2008, Linq a SQL):

result = entRepos.FindAllEntities() .Where(e => e.EntitySearchText.Contains(item)); if (caseSensitive) { result = result .Where(e => e.EntitySearchText.IndexOf(item, System.StringComparison.CurrentCulture) >= 0); }


Intenté esto usando la expresión Lambda, y funcionó.

List<MyList>.Any (x => (String.Equals(x.Name, name, StringComparison.OrdinalIgnoreCase)) && (x.Type == qbType) );


Para realizar consultas sensibles a mayúsculas y minúsculas de SQL a mayúsculas, declare que los campos de "cadena" distinguen entre mayúsculas y minúsculas especificando el tipo de datos del servidor utilizando uno de los siguientes;

varchar(4000) COLLATE SQL_Latin1_General_CP1_CS_AS

o

nvarchar(Max) COLLATE SQL_Latin1_General_CP1_CS_AS

Nota: El ''CS'' en los tipos de clasificación anteriores significa ''Case Sensitive''.

Esto se puede ingresar en el campo "Tipo de datos del servidor" cuando se visualiza una propiedad usando Visual Studio DBML Designer.

Para obtener más información, consulte http://yourdotnetdesignteam.blogspot.com/2010/06/case-sensitive-linq-to-sql-queries.html


Recuerde que hay una diferencia entre si la consulta funciona y si funciona de manera eficiente . Una declaración LINQ se convierte a T-SQL cuando el objetivo de la declaración es SQL Server, por lo que debe pensar en el T-SQL que se produciría.

Usar String.Equals probablemente traerá (todas las filas de SQL Server) y luego hará la comparación en .NET, porque es una expresión .NET que no se puede traducir a T-SQL.

En otras palabras, el uso de una expresión aumentará su acceso a los datos y eliminará su capacidad de hacer uso de los índices. Funcionará en mesas pequeñas y no notará la diferencia. En una mesa grande, podría funcionar muy mal.

Ese es uno de los problemas que existen con LINQ; la gente ya no piensa en cómo se cumplirán las declaraciones que escriben.

En este caso, no hay una manera de hacer lo que quiera sin usar una expresión, ni siquiera en T-SQL. Por lo tanto, es posible que no pueda hacer esto de manera más eficiente. Incluso la respuesta T-SQL dada anteriormente (usando variables con intercalación) probablemente hará que se ignoren los índices, pero si es una tabla grande, entonces vale la pena ejecutar el enunciado y mirar el plan de ejecución para ver si se utilizó un índice. .


Si pasa una cadena que no distingue entre mayúsculas y minúsculas en LINQ-to-SQL, pasará al SQL sin modificaciones y la comparación se realizará en la base de datos. Si desea hacer comparaciones de cadenas insensibles a mayúsculas y minúsculas en la base de datos, todo lo que necesita hacer es crear una expresión lambda que haga la comparación y el proveedor LINQ-to-SQL traducirá esa expresión en una consulta SQL con su cadena intacta.

Por ejemplo, esta consulta LINQ:

from user in Users where user.Email == "[email protected]" select user

se traduce al siguiente SQL por el proveedor LINQ-to-SQL:

SELECT [t0].[Email] FROM [User] AS [t0] WHERE [t0].[Email] = @p0 -- note that "@p0" is defined as nvarchar(11) -- and is passed my value of "[email protected]"

Como puede ver, el parámetro de cadena se comparará en SQL, lo que significa que las cosas deberían funcionar de la manera que usted esperaría.


System.Data.Linq.SqlClient.SqlMethods.Like(row.Name, "test") en mi consulta.

Esto realiza una comparación insensible a mayúsculas y minúsculas.


where row.name.StartsWith(q, true, System.Globalization.CultureInfo.CurrentCulture)