Presentando le novità di ASP.NET 4.0 abbiamo introdotto il QueryExtender
, il nuovo controllo che permette di filtrare i dati senza dover esplicitare clausole WHERE
nelle query ma con una semplice sintassi dichiarativa.
In questo articolo vediamo come usare il QueryExtender
realizzando un esempio pratico: un form di ricerca dati. Nella pagina di ricerca inseriamo diversi filtri, i dati restituiti dalle interrogazioni vengono visualizzati in una GridView
.
La pagina di ricerca
La Web Form di ricerca è composta da quattro caselle di testo, una casella di controllo, un pulsante ed una GridView
:
Company Name:
<asp:TextBox ID="txtCompanyName" runat="server" /><br />
Sales Person:
<asp:TextBox ID="txtVendor" runat="server" /><br />
Expired:
<asp:CheckBox ID="ChkExpired" runat="server" /><br />
CustomerID compreso tra:
<asp:TextBox ID="txtIDmin" runat="server" />
e:
<asp:TextBox ID="txtIDmax" runat="server" />
<br />
<asp:Button ID="Button1" runat="server" Text="Cerca" />
<br /><br />
<asp:GridView ID="GridView1" runat="server" DataKeyNames="CustomerID"
DataSourceID="EntityDataSource1" AllowPaging="true" />
<asp:EntityDataSource ID="EntityDataSource1" runat="server"
ConnectionString="name=AdventureWorksLT2008_DataEntities"
DefaultContainerName="AdventureWorksLT2008_DataEntities"
EntitySetName="Customer" />
La GridView
prende i dati da un EntityDataSource
agganciato ad un Entity Data Model che a sua volta si relaziona con un database Sql Server.
Il database che usiamo è AdventureWorks, messo a disposizione da Microsoft e distribuibile liberamente. Lo troviamo già integrato nell'applicazione allegata come esempio (file AdventureWorksLT2008_Data.mdf
).
L'unica tabella del database che ci interessa è la tabella Customer
che riporta informazioni sui clienti di una società che commercia biciclette che si chiama "Adventure Works Cycles".
La creazione dell'Entity Data Model è molto semplice in quanto realizzabile attraverso la procedura guidata di Visual Studio 2010.
Esempio d'uso di QueryExtender
Aggiungiamo un QueryExtender
alla pagina web selezionandolo dalla casella degli strumenti di Visual Studio 2010 e trascinandolo nella pagina. Aggiungiamo al QueryExtender
i filtri che useremo nel nostro esempio. Vediamo il markup corrispondente:
<asp:QueryExtender ID="QueryExtender1" runat="server"
TargetControlID="EntityDataSource1">
<asp:OrderByExpression DataField="LastName" Direction="Ascending" />
<asp:SearchExpression SearchType="Contains" DataFields="CompanyName">
<asp:ControlParameter ControlID="txtCompanyName" />
</asp:SearchExpression>
<asp:PropertyExpression >
<asp:ControlParameter ControlID="txtVendor" Name="SalesPerson" />
</asp:PropertyExpression>
<asp:PropertyExpression >
<asp:ControlParameter ControlID="ChkExpired" Name="Expired" />
</asp:PropertyExpression>
<asp:RangeExpression DataField="CustomerID"
MaxType="Inclusive" MinType="Exclusive">
<asp:ControlParameter ControlID="txtIDmin" />
<asp:ControlParameter ControlID="txtIDmax" />
</asp:RangeExpression>
</asp:QueryExtender>
Il QueryExtender può essere usato solo con due tipi di DataSource: LinqDataSource
e l'EntityDataSource
. Nel nostro esempio lo agganciamo all'EntityDataSource
nominato EntityDataSource1
attraverso la proprietà TargetControlID
.
Questo componente ci offre molte opzioni di filtraggio, che possono essere usate sia singolarmente, sia congiuntamente. Esaminiamo le opzioni che abbiamo usato nel nostro esempio.
OrderByExpression
È usata per ordinare i dati in maniera ascendente o discendente. Nel nostro esempio ordiniamo i clienti in base al loro cognome con direzione ascendente. Attraverso la proprietà DataField
indichiamo il campo LastName
come oggetto dell'ordinamento e attraverso la proprietà Direction
indichiamo che l'ordinamento deve essere ascendente.
SearchExpression
Serve a confrontare uno o più campi di testo con un valore di tipo stringa che forniamo in ingresso. Possiamo effettuare tre tipi di confronto:
Tipo di confronto | Descrizione |
---|---|
SearchType="contains" |
verifica che la stringa sia contenuta all'interno di un testo |
SearchType="starts with" |
verifica che la stringa sia contenuta contenuta all'inizio di un testo |
SearchType="ends with" |
verifica che la stringa sia contenuta contenuta alla fines di un testo |
Specifichiamo il campo in cui effettuare la ricerca con la proprietà DataFields
. Il valore di comparazione è fornito attraverso la proprietà ControlID
della classe ControlParameter
.
Nel nostro esempio ricerchiamo tutte quelle società che hanno la stringa "Cycle"
nel nome. Raggiungiamo questo risultato dichiarando una espressione di tipo SearchExpression
nella quale poniamo la proprietà SearchType
a contains
e la proprietà DataFields
a CompanyName
. CompanyName
è il campo della tabella Customer che indica il nome della società del cliente. Riusciamo a fornire il valore di comparazione usando la casella di testo txtCompanyName
.
Nella SearchExpression
aggiungiamo, quindi, un controllo ControlParameter
ed impostiamo la proprietà ControlID
sulla suddetta casella di testo. Mandiamo in esecuzione la nostra applicazione e scriviamo Cycle
nella casella di testo etichettata Company Name. Clicchiamo su Esegui
e verifichiamo che la GridView venga caricata con i clienti che appartengono a società che nel loro nome hanno la stringa "Cycle"
.
PropertyExpression
Questa espressione confronta un campo con un valore fornito in ingresso. Nel nostro esempio usiamo una prima PropertyExpression
per cercare quei clienti che hanno un determinato venditore, rappresentato dal campo SalesPerson
, ed una seconda per cercare quei clienti che sono ancora attivi o ormai scaduti, rappresentati dal campo Expired
.
Come per le altre espressioni usiamo la classe ControlParameter
per specificare il campo oggetto della ricerca, valorizzando la proprietà Name
. Con la proprietà ControlID
indichiamo invece il controllo dal quale prendere il valore da confrontare.
RangeExpression
Questa espressione consente di determinare se un campo di tipo intero sia maggiore o minore di un certo valore o se è compreso tra due valori.
La proprietà DataField
specifica il campo sul quale effettuare la ricerca. Con la proprietà MinType
si indica se includere o escludere il valore minimo dalla ricerca e con la proprietà MaxType
si indica se includere o escludere il valore massimo dalla ricerca.
Nel nostro esempio ricerchiamo tutti quei clienti che hanno il campo CustomerID
maggiore di 325
e minore o uguale a 30018
(325 < CustomerID <= 30018
). In figura vediamo valorizzate le caselle di testo che rappresentano l'intervallo (notiamo che il cliente con codice identificativo uguale a 325 è stato escluso).
CustomExpression
È possibile specificare anche delle query LINQ ad hoc che vengono eseguite in risposta ad un evento. In maniera simile, usando l'espressione MethodExpression
, è possibile specificare anche delle query LINQ ad hoc che vengono eseguite chiamando un metodo.
Testare l'esempio
Come abbiamo detto possiamo applicare i filtri singolarmente o congiuntamente. Mandiamo in esecuzione la nostra applicazione e inseriamo la parola "Cycle" nella casella di testo "Company Name". Clicchiamo sul pulsante Esegui, questo manda in esecuzione la query che ricerca quei clienti che appartengono ad una società il cui nome contiene la parola "Cycle".
Adesso inseriamo la parola "adventure-works/pamela0" nella casella di testo "Sales Person". Clicchiamo su Esegui, questo manda in esecuzione la query che ricerca quei clienti che appartengono ad una società il cui nome contiene la parola "Cycle" e che hanno come agente di vendita la persona "adventure-works/pamela0". Se avessimo voluto applicare il solo filtro sugli agenti di vendita avremmo dovuto cancellare la casella Company Name.
Ora lasciamo vuota la casella di controllo Expired e inseriamo i valori 325
e 30018
nelle ultime due caselle di testo della pagina. Cliccando su Esegui si manda in esecuzione la query che ricerca quei clienti che appartengono ad una società il cui nome contiene la parola "Cycle", che hanno come agente di vendita la persona "adventure-works/pamela0", che sono ancora clienti attivi e il cui codice identificativo è compreso tra 325
(escluso) e 30018
. Il risultato della query è visibile in figura 2.
Conclusioni
Il QueryExtender è un controllo molto utile per filtrare i dati di una query senza dover ricorrere alla clausola WHERE
. Un limite è rappresentato dal fatto che il QueryExtender attualmente può accettare solo due tipi di data source.
Questo controllo è certamente utile quando abbiamo bisogno di scrivere poco codice e ottenere rapidamente un risultato.
Riferimenti
Per approfondimenti sul QueryExtender:
Per approfondimenti su come realizzare un Entity Data Model: