none
Extension Method in LINQ RRS feed

  • Domanda

  • Buongiorno a tutti.

    Sto costruendo una query in Linq e VB. Net 2010 che faccia un filtro su alcuni campi solo se certe variabili hanno un certo valore.

    Ad esempio, facendo finta di avere una tabella con un'anagrafia di persone che lavorano in un ospedale e una tabella con i reparti dove lavorano (con possibilità ad esempio che al mattino lavora in reparto e nel pomeriggio in un altro) ho cretao delle checkbox e se isCheck=True allora mi deve tirare fuori questi dati.

    Scrivo quindi la query:

    dim query= from hh in DatabaseEntities.personale

    join qq in lavorichefanno on hh.IDPersona equals qq.IDPersona

    select new with {hh.Cognome,hh.Nome}


    Ora ho diversi filtri

    FiltroDentista=True

    FiltroOttica=False

    Ho una tabella poi che corrisponde a 1= Dentista, 2= Ottico, etc etc

    etc etc in base ai check sulla window.


    Dovrei scrivere ogni query per ogni combianzione:

    If FiltroDentista=True and FiltroOttica=False then query= query.where (Function(p) p.Lavoro che fa =1)

    If FiltroDentista=True and FiltroOttica=True then query= query.where (Function(p) p.Lavorochefa =1 or p.Lavorochefa=2)


    Con Extension Method o altre tecnologie è possibile scrivere una sola query del tipo:

    query=query.where(Function(p) if (FiltroDentista=True then p.lavorochefa=1) or (if FiltroOttica=True then p.lavorochefa=2) etc etc)  ?

    Altrimenti scrivere la combinazione di 20 checkbox vero o falso diventano 400 query linq.

    Voi come fareste?

    Grazie in anticipo.

    Cordiali saluti.

    Piero Sbressa

    domenica 11 marzo 2012 14:57

Risposte

Tutte le risposte

  • Più che gli extension method probabilmente devi costruirti un meccanismo dinamico. Questo, in LINQ, si ottiene attraverso gli expression tree e le lambda. Non è per niente banale ed intuitivo, ma è sicuramente il modo più efficiente.

    Costruendo un expression tree puoi bypassare il problema del dover predisporre una query per ogni situazione possibile. La documentazione MSDN ne parla qui:

    http://msdn.microsoft.com/en-us/library/bb397951.aspx

    Puoi banalmente cercare sui motori di ricerca "dynamic LINQ queries" e trovare molti risultati, di cui svariati extra MSDN. Ad esempio questo bel blog post: http://tomasp.net/articles/dynamic-linq-queries.aspx


    Alessandro Del Sole
    Microsoft MVP - Visual Basic: development
    http://community.visual-basic.it/alessandro/

    • Contrassegnato come risposta Piero Sbressa domenica 13 maggio 2012 07:03
    domenica 11 marzo 2012 18:34
  • Grazie Alessandro.

    Mi sono fatto aiutare da Carmelo La Monica in termini pratici.

    Lui ha costruito qualcosa come prima una enumerazione su quali checkbox hanno il check e quindi per ogni check si usa la stessa query all'interno del ciclo.

    I risultati vengono aggiunti in una richtextbox, come potrebbero essere aggiunti in una listbox a in una sorgente dati in generale per rielaborazione seguente.

    Questo è il codice che mi ha passato:

    foreach (
                    var myRadioButton in
                    GroupBox1.Controls.Cast<RadioButton>().Where(myRadioButton => myRadioButton.Checked.Equals(true)))
                {
                    _filtro = myRadioButton.Text;
                }


                foreach (
                    var myCheckBox in
                        GroupBox3.Controls.Cast<CheckBox>().Where(myCheckBox => myCheckBox.Checked.Equals(true)))
                {
                    var box = myCheckBox;
                    var result = work.
                        Where(
                            w =>
                            w.Attivita.Equals(box.Text) && w.Stato.Equals(_filtro)).
                        Join(customers, job => job.ID, cust => cust.CustomerID,
                             (job, name) => new {name.Nome, name.Cognome , job.Attivita}).
                        OrderBy(a => a.Cognome).Distinct();

                    foreach (var mylist in result.Where(mylist => !mylist.Equals(null)))
                    {
                        richTextBox1.Text += "Nome" + '\t' + mylist.Nome + '\t' + "Cognome" + '\t' + mylist.Cognome + '\t' + "Attività svolte" + '\t' + mylist.Attivita + '\t' + "Stato attuale" + '\t' + _filtro + '\n';
                    }
                }
            }

    domenica 13 maggio 2012 07:08