Saltar al contenido

Comparación entre mayúsculas y minúsculas de LINQ to Entities

Bienvenido a nuestra web, ahora hallarás la solucíon de lo que buscas.

Solución:

Eso es porque estás usando LINQ a entidades que en última instancia convierte sus expresiones Lambda en declaraciones SQL. Eso significa que la distinción entre mayúsculas y minúsculas está a merced de su servidor SQL, que por defecto tiene SQL_Latin1_General_CP1_CI_AS Intercalación y eso NO distingue entre mayúsculas y minúsculas.

Utilizando ObjectQuery.ToTraceString ver la consulta SQL generada que se envió realmente a SQL Server revela el misterio:

string sqlQuery = ((ObjectQuery)context.Thingies
        .Where(t => t.Name == "ThingamaBob")).ToTraceString();

Cuando creas un LINQ a entidades consulta, LINQ a entidades aprovecha el analizador LINQ para comenzar a procesar la consulta y la convierte en un árbol de expresión LINQ. El árbol de expresiones LINQ luego se pasa a Servicios de objetos API, que convierte el árbol de expresiones en un árbol de comandos. Luego se envía al proveedor de almacenamiento (p. ej., SqlClient), que convierte el árbol de comandos en el texto de comando de la base de datos nativa. La consulta se ejecuta en el almacén de datos y los resultados son Materializado dentro Objetos de entidad por Servicios de objetos. No se ha puesto ninguna lógica intermedia para tener en cuenta la distinción entre mayúsculas y minúsculas. Por lo tanto, no importa qué caso coloque en su predicado, su SQL Server siempre lo tratará de la misma manera a menos que cambie su SQL Server Collates para esa columna.

Solución del lado del servidor:

Por lo tanto, la mejor solución sería cambiar la colación de los Nombre columna en el cositas mesa para COLLATE Latin1_General_CS_AS que distingue entre mayúsculas y minúsculas al ejecutar esto en su servidor SQL:

ALTER TABLE Thingies
ALTER COLUMN Name VARCHAR(25)
COLLATE Latin1_General_CS_AS

Para obtener más información sobre el Cotejos de SQL Serverecha un vistazo a SERVIDOR SQL Intercalar búsqueda de consulta SQL sensible a mayúsculas y minúsculas

Solución del lado del cliente:

La única solución que puede aplicar en el lado del cliente es usar LINQ a objetos para hacer otra comparación que no parece ser muy elegante:

Thingies.Where(t => t.Name == "ThingamaBob")
        .AsEnumerable()
        .First(t => t.Name == "ThingamaBob");

WHERE las condiciones en SQL Server no distinguen entre mayúsculas y minúsculas de forma predeterminada. Hágalo con distinción entre mayúsculas y minúsculas cambiando las intercalaciones predeterminadas de la columna (SQL_Latin1_General_CP1_CI_AS) para SQL_Latin1_General_CP1_CS_AS.

La forma frágil de hacer esto es con código. Agregue un nuevo archivo de migración y luego agregue esto dentro del Up método:

public override void Up()

   Sql("ALTER TABLE Thingies ALTER COLUMN Name VARCHAR(MAX) COLLATE SQL_Latin1_General_CP1_CS_AS NOT NULL");

Pero

Puede crear una anotación personalizada llamada “CaseSensitive” utilizando las nuevas características de EF6 y puede decorar sus propiedades de esta manera:

[CaseSensitive]
public string Name  get; set; 

Esta publicación de blog explica cómo hacerlo.

Puedes añadir [CaseSensitive] anotación para EF6+ Code-first

Añadir estas clases

[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
public class CaseSensitiveAttribute : Attribute

    public CaseSensitiveAttribute()
    
        IsEnabled = true;
    
    public bool IsEnabled  get; set; 


public class CustomSqlServerMigrationSqlGenerator : SqlServerMigrationSqlGenerator

    protected override void Generate(AlterColumnOperation alterColumnOperation)
    
        base.Generate(alterColumnOperation);
        AnnotationValues values;
        if (alterColumnOperation.Column.Annotations.TryGetValue("CaseSensitive", out values))
        
            if (values.NewValue != null && values.NewValue.ToString() == "True")
            
                using (var writer = Writer())
                
                    //if (System.Diagnostics.Debugger.IsAttached == false) System.Diagnostics.Debugger.Launch();

                    // https://github.com/mono/entityframework/blob/master/src/EntityFramework.SqlServer/SqlServerMigrationSqlGenerator.cs
                    var columnSQL = BuildColumnType(alterColumnOperation.Column); //[nvarchar](100)
                    writer.WriteLine(
                        "ALTER TABLE 0 ALTER COLUMN 1 2 COLLATE SQL_Latin1_General_CP1_CS_AS 3",
                        alterColumnOperation.Table,
                        alterColumnOperation.Column.Name,
                        columnSQL,
                        alterColumnOperation.Column.IsNullable.HasValue == false 
            
        
    


public class CustomApplicationDbConfiguration : DbConfiguration

    public CustomApplicationDbConfiguration()
    
        SetMigrationSqlGenerator(
            SqlProviderServices.ProviderInvariantName,
            () => new CustomSqlServerMigrationSqlGenerator());
    

Modifique su DbContext, agregue

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    
        modelBuilder.Conventions.Add(new AttributeToColumnAnnotationConvention(
                "CaseSensitive",
                (property, attributes) => attributes.Single().IsEnabled));
        base.OnModelCreating(modelBuilder);
    

Entonces hazlo

Sensible a mayúsculas y minúsculas de migración adicional

Actualizar base de datos

basado en el artículo https://milinaudara.wordpress.com/2015/02/04/case-Sensible-search-using-entity-framework-with-custom-annotation/ con algunas correcciones de errores

Si piensas que ha resultado de ayuda nuestro post, nos gustaría que lo compartas con más programadores de este modo contrubuyes a difundir esta información.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *