2009-04-13 16 views
8

Estoy intentando escribir una consulta SQL que filtra una vista de cuadrícula por los campos que se ingresan. Hay cuatro campos, título, nombre, apellido y Company.Name.Comprobación de consulta LINQ SQL si un campo de objeto no es nulo

Las tres primeras están bien, ya que nunca son nulas, pero la cuarta puede ser nula. La siguiente LINQ consulta funciona bien:

var listofclients = from client in allcients 
        where client.Title.ToLower().Contains(titletxtbox.Text.Trim().ToLower()) 
        where client.Firstname.ToLower().Contains(firstnametxtbox.Text.Trim().ToLower()) 
        where client.Surname.ToLower().Contains(surnametxtbox.Text.Trim().ToLower()) 
        orderby client.Name 

Pero cuando intento poner un filtro en él para la empresa en la que se producirá un error en tiempo de ejecución cuando la empresa es nulo

var listofclients = from client in allcients 
        where client.Title.ToLower().Contains(titletxtbox.Text.Trim().ToLower()) 
        where client.Firstname.ToLower().Contains(firstnametxtbox.Text.Trim().ToLower()) 
        where client.Surname.ToLower().Contains(surnametxtbox.Text.Trim().ToLower()) 
        where client.Company.Name.ToLower().Contains(companynametxtbox.Text.Trim().ToLower()) 
        orderby client.Name 

lo que yo gustaría saber, ¿hay alguna forma de generar la consulta para que solo se filtre cuando el campo client.Company no sea nulo?

También soy vulnerable a la inyección de SQL o similar cuando lo saco directamente de los campos de cuadros de texto como este. Sé que en este caso no está conectado a la base de datos, pero si fuera así, podrían hacer una caída. O incluso si no está conectado a la base de datos, ¿podrían jugar con los objetos de la lista?

Gracias

Jon Hawkins

Respuesta

5

Asumo desea que todos los registros que coinciden en que la empresa es nulo, pero filtrada por su nombre cuando existe la Compañía. Lo siguiente debería hacer eso. Además, no necesita preocuparse por la inyección SQL, ya que LINQToSQL utiliza consultas parametrizadas. Tendrá que preocuparse por limpiar cualquier código HTML que pueda estar en los controles del cliente si tiene la intención de hacer inserciones de ellos y mostrar cualquiera de los valores en la web para evitar los ataques XSS.

var listofclients = from client in allcients 
        where client.Title.ToLower().Contains(titletxtbox.Text.Trim().ToLower()) 
        where client.Firstname.ToLower().Contains(firstnametxtbox.Text.Trim().ToLower()) 
        where client.Surname.ToLower().Contains(surnametxtbox.Text.Trim().ToLower()) 
        where client.Company == null || client.Company.Name.ToLower().Contains(companynametxtbox.Text.Trim().ToLower()) 
        orderby client.Name 
3
var listofclients = from client in allcients 
        orderby client.Name 
        select client; 

if (string.IsNullOrEmpty(titletxtbox.Text)) 
listofclients = listofclients.Where(l=>l.Title.Contains(titletxtbox.Text)) 

........

Algo como esto

+0

Eso hará el filtrado en el conjunto de datos recuperado. Me imagino que Jon quiere que el Nombre de la empresa se incluya como parte de la selección de SQL. – sipwiz

+0

@sipwiz: No. Mientras no haya ToList() o un llamado equivalente en "de ... seleccionar", el objeto listofclient es un IQueryable (por lo que no se recuperan datos en este punto). Lo que significa que la solicitud aún no se ejecuta, por lo que la cláusula "where" se realizará ANTES de recuperar los datos. –

+0

Sí exactamente cuando llamas a ToList o un método similar ocurre la invocación de sql real. – omoto

1

1) LINQ to SQL utiliza parámetros en sus consultas, por lo que no es vulnerable a la inyección sql. SIN EMBARGO, NUNCA CONFÍE EN LA ENTRADA DEL USUARIO.

2) Linq no proporciona verificación nula gratuita, lo siento. Esto se puede hacer con un simple método de extensión, aunque, para mantener su ajuste consulta LINQ y en forma:

public static class StringExtensions 
{ 
    public static bool ContainsEx(this string me, string other) 
    { 
    if(me == null || other == null) return false; 
    // This is a better way of performing a case-insensitive Contains 
    return me.IndexOf(other, 0, StringComparison.OrdinalIgnoreCase) != -1; 
    } 
} 
+0

¡dangit! Odio editar el código para hacerlo mejor, ¡solo para introducir un error! – Will

Cuestiones relacionadas