2009-04-13 9 views
8

Sto provando a scrivere una query SQL che filtra una griglia con i campi immessi. Ci sono quattro campi, titolo, nome, cognome e Company.Name.LINQ Query SQL verificare se un campo oggetto non è nullo

I primi tre vanno bene perché non sono mai nulli ma il quarto può essere nullo. Il seguente LINQ Query funziona bene:

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 

Ma quando provo e mettere un filtro in esso per l'azienda per cui si ottiene un errore in fase di esecuzione, quando la società è nullo

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 

quello che vorrei piacerebbe sapere, c'è un modo per costruire la query in modo che si limiterà a filtrare solo quando il campo client.Company non è nullo.

Sono inoltre vulnerabile all'iniezione SQL o simile quando richiamo direttamente dai campi della casella di testo come questo. So che in questo caso non è collegato al DB, ma se lo fosse, potrebbero fare una caduta. O anche se non è collegato al db, potrebbero armeggiare con gli oggetti nella lista?

Grazie

Jon Hawkins

risposta

5

che sto supponendo che si desidera tutti i record corrispondenti in cui società è nullo, ma filtrato per nome quando esiste la Società. Il seguente dovrebbe farlo. Inoltre, non è necessario preoccuparsi dell'iniezione SQL poiché LINQToSQL utilizza query parametrizzate. Dovrai preoccuparti di ripulire qualsiasi HTML che possa essere presente nei controlli del client se intendi eseguire inserimenti da essi e visualizzare uno qualsiasi dei valori sul web per evitare attacchi 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)) 

........

Qualcosa di simile

+0

Questo farà il filtraggio sul set di dati recuperato. Immagino che Jon voglia inserire il nome della società come parte della selezione SQL. – sipwiz

+0

@sipwiz: No. Finché non è presente alcuna ToList() o equivalente chiamata "da ... select", l'oggetto listofclient è un IQueryable (quindi nessun dato recuperato a questo punto). Ciò significa che la richiesta non viene ancora eseguita, quindi la clausola "where" verrà eseguita PRIMA di recuperare i dati. –

+0

Sì esattamente solo quando si chiama ToList o metodo simile, avviene l'invocazione di sql reale. – omoto

1

1) LINQ to SQL utilizza parametri nelle sue richieste, in modo da non è vulnerabile a SQL injection TUTTAVIA, NON FIDUCIA MAI L'INGRESSO UTENTE.

2) Linq non fornisce il controllo nullo gratuito, mi spiace. È possibile raggiungere questo obiettivo con un semplice metodo di estensione, tho, per mantenere il vostro LINQ query di assetto e in 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 modificare il codice per renderlo migliore, solo per introdurre un bug! – Will

Problemi correlati