2009-11-09 12 views
5
public static void MyFunction(MyErrorClass err) 
{ 
    var query = from filter in DataContext.ErrorFilters select filter; 
    query = query.Where(f => err.ErrorMessage.Contains(f.ErrorMessage)); 
    List<ErrorFilter> filters = query.ToList(); 
    //...more code 
} 

Così sto avendo alcuni problemi con il codice di cui sopra, e sto ricevendo l'errore dalla riga dell'oggetto al linea con query.ToList(). Ecco cosa sto cercando di fare:"Solo gli argomenti che possono essere valutati sul client sono supportati per il metodo String.Contains"

Prima di tutto, ho una classe di errore personalizzata, MyErrorClass. Ogni volta che si verifica un errore sul mio sito, creo un oggetto MyErrorClass dall'eccezione, memorizzo tutti i dati dall'eccezione in quell'oggetto e memorizzo le informazioni nel database.

Una delle proprietà delle eccezioni di cui sto tenendo traccia è il messaggio per l'errore (ErrorMessage). Ho una tabella ErrorFilters impostata nel database in cui l'utente può filtrare gli errori in base allo ErrorMessage. Quindi affermano che ci sono un sacco di errori che dicono "System.Data.SqlClient.SqlException: Timeout scaduto. Il periodo di timeout è trascorso prima del completamento dell'operazione o il server non risponde.", E si desidera ignorarli. Basta aggiungere un filtro al database con ErrorMessage come "timeout scaduto" e impostarlo in modo da ignorarlo.

Ora, la mia classe precedente è impostata per rilevare un errore e decidere se l'errore deve essere filtrato. Sto cercando di ottenere un elenco di tutti i filtri che hanno un ErrorMessage corrispondente a quello dell'errore.

Sono sicuro che questa è una soluzione semplice, ma non so come risolverlo.

+0

Questo metodo restituisce void, cosa dovrebbe fare? Se deve controllare se l'errore deve essere mostrato, allora dovrebbe restituire un valore booleano e una correzione può essere trovata. Altrimenti, spiega la domanda un po 'meglio. –

+1

La funzione sta facendo molte altre cose che non sono rilevanti per l'errore, tutto quello che conta sono quelle 3 righe in cui sto cercando di ottenere un elenco di filtri che corrispondono all'errore. Ho spiegato tutto ciò che devi sapere, che altro ti stai chiedendo? –

risposta

0

Sembra che si dovrebbe usare f.ErrorMessage.Contains(err.ErrorMessage) - da linq a sql dovrebbe quindi convertirlo in WHERE ErrorFilter.ErrorMessage LIKE %err.ErrorMessage%. Il problema con il modo in cui lo hai è che l'SQL generato avrebbe bisogno di una stringa dinamica per corrispondere alla clausola where, e quindi poteva essere filtrata solo sul client.

Incidentalmente, la linea var query = from filter in DataContext.ErrorFilters select filter; non è richiesto e si può solo fare:

var filters = DataContext.ErrorFilters.Where(f => f.ErrorMessage.Contains(err.ErrorMessage)).ToList();

EDIT:

Ok vedo quello che stai cercando di fare ora, ma io non sono certo se questo è possibile in linq2sql. Si potrebbe creare una stored procedure e aggiungere che al DataContext e fare la mappatura dall'uscita ad una sequenza di oggetti ErrorFilter:

create procedure GetMatchingFilters @message varchar(500) 
as 
begin 
    select * 
    from ErrorFilter 
    where @message LIKE '%'+ErrorMessage+'%' 
end 

Poi, nel tuo DataContext si può fare:

DataContext 
    .GetMatchingFilters(err.ErrorMessage) 
    .Select(result => new ErrorFilter {...}) 
    .ToList(); 
+0

Il problema è che sarebbe molto difficile filtrare in base a ErrorMessage. ErrorMessage è in genere molto lungo e dovresti essere in grado di creare un filtro semplicemente digitando "timeout scaduto". Utilizzando il metodo, l'utente dovrebbe avere il messaggio ErrorMessage per il filtro esattamente identico a ErrorMessage per l'errore. –

+0

No, dovrebbe funzionare come hai descritto, la query sarà simile a SELECT * FROM ErrorFilters WHERE ErrorMessage LIKE% someString%. A meno che non abbia frainteso il problema ... – Lee

+0

Inverti 'f.ErrorMessage.Contains (err.ErrorMessage))' a 'err.ErrorMessage.Contains (f.ErrorMessage))' –

4

Hmm. .. Sembra che la traduzione di Linq2SQL IndexOf sia più intelligente rispetto a Contains. Questo dovrebbe funzionare:

public static void MyFunction(MyErrorClass err) 
{ 
    var query = DataContext.ErrorFilters; 
    query = query.Where(f => err.ErrorMessage.IndexOf(f.ErrorMessage)>=0); 
    List<ErrorFilter> filters = query.ToList(); 
    //...more code 
} 

In LINQPad si può vedere questo utilizza CHARINDEX, perché abbiamo chiesto più di un semplice "contiene", piuttosto "dove si trova", ma è felice di lavorare con server- espressioni laterali.

+1

Questa è pura brillantezza. Le persone sono state alla ricerca di una soluzione a questo per anni !! .Seleziona (x => "testo1 | testo2 | testo3" .IndexOf (x.colonna)> = 0) – benpage

+0

@benpage In difesa della comunità, dopo aver postato questa risposta ho notato [altro] (http: // StackOverflow. it/a/19791382/256431) [luoghi] ​​(http://stackoverflow.com/a/7574433/256431) su SO che ha già menzionato questo concetto anni fa. –

Problemi correlati