Criteri facoltativi LINQ to SQL Where

Sto lavorando con una query LINQ a SQL e ho incontrato un problema in cui ho 4 campi facoltativi per filtrare il risultato dei dati. Con l’opzione, voglio dire, ha la possibilità di inserire un valore o meno. In particolare, alcune caselle di testo che potrebbero avere un valore o avere una stringa vuota e alcuni elenchi a discesa che avrebbero potuto avere un valore selezionato o forse no …

Per esempio:

using (TagsModelDataContext db = new TagsModelDataContext()) { var query = from tags in db.TagsHeaders where tags.CST.Equals(this.SelectedCust.CustCode.ToUpper()) && Utility.GetDate(DateTime.Parse(this.txtOrderDateFrom.Text)) = tags.ORDDTE select tags; this.Results = query.ToADOTable(rec => new object[] { query }); } 

Ora ho bisogno di aggiungere i seguenti campi / filtri, ma solo se sono forniti dall’utente.

  1. Numero prodotto: viene da un’altra tabella che può essere unita a tagHeaders.
  2. Numero PO: un campo all’interno della tabella TagHeaders.
  3. Numero ordine – Simile a PO #, solo colonna diversa.
  4. Stato prodotto: se l’utente lo ha selezionato da un menu a discesa, è necessario applicare qui il valore selezionato.

La query che ho già sta funzionando alla grande, ma per completare la funzione, devo essere in grado di aggiungere questi altri 4 elementi nella clausola where, non so come!

Puoi codificare la query originale:

 var query = from tags in db.TagsHeaders where tags.CST.Equals(this.SelectedCust.CustCode.ToUpper()) && Utility.GetDate(DateTime.Parse(this.txtOrderDateFrom.Text)) <= tags.ORDDTE && Utility.GetDate(DateTime.Parse(this.txtOrderDateTo.Text)) >= tags.ORDDTE select tags; 

E poi in base a una condizione, aggiungi ulteriori vincoli.

 if(condition) query = query.Where(i => i.PONumber == "ABC"); 

Non sono sicuro di come codificarlo con la syntax della query ma id funziona con un lambda. Funziona anche con la syntax della query per la query iniziale e un lambda per il filtro secondario.

Puoi anche includere un metodo di estensione (in basso) che ho codificato fino a includere istruzioni condizionali. (Non funziona bene con la syntax della query):

  var query = db.TagsHeaders .Where(tags => tags.CST.Equals(this.SelectedCust.CustCode.ToUpper())) .Where(tags => Utility.GetDate(DateTime.Parse(this.txtOrderDateFrom.Text)) <= tags.ORDDTE) .Where(tags => Utility.GetDate(DateTime.Parse(this.txtOrderDateTo.Text)) >= tags.ORDDTE) .WhereIf(condition1, tags => tags.PONumber == "ABC") .WhereIf(condition2, tags => tags.XYZ > 123); 

Il metodo di estensione:

 public static IQueryable WhereIf( this IQueryable source, bool condition, Expression> predicate) { if (condition) return source.Where(predicate); else return source; } 

Ecco lo stesso metodo di estensione per IEnumerables:

 public static IEnumerable WhereIf( this IEnumerable source, bool condition, Func predicate) { if (condition) return source.Where(predicate); else return source; } 

Basta usare un controllo condizionale per l’esistenza del parametro. Per esempio:

 where (string.IsNullOrEmpty(ProductNumber) || ProductNumber == tags.productNumber) 

In questo modo, se il codice prodotto non è inserito, quell’espressione restituirà true in tutti i casi, ma se viene immessa restituirà true solo quando corrisponde.

Hai la possibilità di OR con ||.

Dai un’occhiata a questo thread, dato che potrebbe darti dei buoni consiglieri: equivalente al CQ LINQ di una query SQL piuttosto complessa