If, for example, you wanted to include a bullet list of each product in an individual group, you would simply add anotherTemplateField, insert a BulletList control and bind it to the Pro
Trang 1<asp:querystringparameter DefaultValue="0" Name="CustomerID"
QueryStringField="cid" Type="String" />
</whereparameters>
</asp:LinqDataSource>
You can add multipleWhereparameters that the control will automatically concatenate in itsWhere
property using theANDoperator You can manually change the default value of theWhereproperty if you want to have multipleWhereParametersdefined, but only use a subset, or if you want to change which parameters are used dynamically at runtime This is shown in Listing 7-12, where the LinqDataSource
control has severalWhereparameters defined, but by default is using only one
Listing 7-12: Using one of multiple defined WhereParameters
<asp:LinqDataSource ID="LinqDataSource1" runat="server"
ContextTypeName="NorthwindDataContext" TableName="Customers"
Select="new (CustomerID, ContactName, ContactTitle, Region)"
Where="Country == @Country"
OrderBy="Region, ContactTitle, ContactName">
<whereparameters>
<asp:querystringparameter DefaultValue="0" Name="CustomerID"
QueryStringField="cid" Type="String" />
<asp:querystringparameter DefaultValue="USA" Name="Country"
QueryStringField="country" Type="String" />
<asp:FormParameter DefaultValue="AZ" Name="Region"
FormField="region" Type="String" />
</whereparameters>
</asp:LinqDataSource>
In this case, although threeWhereParametersare defined, theWhereproperty uses only theCountry
parameter It would be simple to change theWhereproperty’s value at runtime to use any of the defined parameters, based perhaps on a configuration setting set by the end user
The LinqDataSource control also includes a property calledAutoGenerateWhereClause, which can sim-plify the markup created by the control When set toTrue, the property causes the control to ignore the value of theWhereproperty and automatically use each parameter specified in theWhereparameters
collection in the query’sWhereclause
Defining an OrderBy Clause
When defining anOrderByclause, by default the wizard simply creates a comma-delimited list of fields
as the value for the control’sOrderByproperty The value of theOrderByproperty is then appended to the control’s LINQ query when it is executed
The control also exposes anOrderByParameterscollection, which you can also use to specifyOrderBy
values However, in most cases using the simpleOrderByproperty will be sufficient You would need to the useOrderByparameters collection only if you need to determine the value of a variable at runtime, and then order the query results based on that value
Grouping Query Data
The LinqDataSource control also makes it easy to specify a grouping for the resultset returned by the
query In the configuration wizard, you can select the Group By field for the query Once a field is
selected, the wizard then creates a default projection based on the groupby field The projection includes
Trang 2two fields by default, the first calledkey, which represents the group objects specified in theGroupBy
property, and the second calleditwhich represents the grouped objects You can also add your own
columns to the projection and execute functions against the grouped data such asAverage,Min,Max, and
Count Listing 7-13 demonstrates a very simple grouping using the LinqDataSource control
Listing 7-13: Simple Data Grouping
<asp:LinqDataSource ID="LinqDataSource1" runat="server"
ContextTypeName="NorthwindDataContext" TableName="Products"
Select="new (key as Category, it as Products,
Average(UnitPrice) as Average_UnitPrice)"
GroupBy="Category">
</asp:LinqDataSource>
You can see in this sample that the Products table has been grouped by itsCategoryproperty The
LinqDataSource control created a new projection containing thekey(aliased asCategory) andit(aliased
asProducts) fields Additionally, the custom fieldaverage_unitpricehas been added, which calculates
the average unit price of the products in each category When you execute this query and bind the results
to a GridView, a simple view of the calculated average unit price is displayed The Category and Products
are not displayed because they are complex object types, and the GridView is not capable of directly
displaying them
You can access the data in either key by using the standardASP.NET Eval()function In a GridView you
would do this by creating aTemplateField, and usingItemTemplateto insert theEvalstatement as
shown here:
<asp:TemplateField>
<ItemTemplate>
<%# Eval("Category.CategoryName") %>
</ItemTemplate>
</asp:TemplateField>
In this case,TemplateFielddisplays theCategoryNamefor each grouped category in the resultset
Accessing the grouped items is just as easy If, for example, you wanted to include a bullet list of each
product in an individual group, you would simply add anotherTemplateField, insert a BulletList control
and bind it to the Products field returned by the query, as shown next:
<asp:TemplateField>
<ItemTemplate>
<asp:BulletedList DataSource=’<%# Eval("Products") %>’
DataTextField="ProductName" runat="server" ID="BulletedList" />
</ItemTemplate>
</asp:TemplateField>
Data Concurrency
Like the SqlDataSource control, the LinqDataSource control allows for data concurrency checks when
updating or deleting data As its name implies, theStoreOriginalValuesInViewStateproperty
indi-cates whether the data source control should store the original data values in ViewState Doing this when
using LINQ to SQL as the underlying data object, allows LINQ to SQL to perform data concurrency
checking before submitting updates, or deleting data
306
Trang 3Storing the original data in ViewState, however, can cause the size of your Web page to grow
significantly, affecting the performance of your Web site, so you may wish to disable the storing of data
in ViewState If you do, recognize that you are now responsible for any data concurrency checking that your application requires
LinqDataSource Events
The LinqDataSource control also includes a number of useful events that you can use to react to actions taken by the control at runtime Standard before and after events for Select, Insert, Update, and Delete
actions are all exposed and allow you to add, remove, or modify parameters from the control’s various parameter collections, or even cancel the event entirely
Additionally, the post action events allow you to determine whether an exception has occurred while
attempting to execute an Insert, Update, or Delete If an exception has occurred, these events allow you
to react to those exceptions, and either mark the exception as handled, or allow it to continue to bubble
up through the application
AccessDataSource Control
Although you can use the SqlDataSource to connect to Access databases, ASP.NET also provides a special AccessDataSourcecontrol This control gives you specialized access to Access databases using the Jet
Data provider, but it still uses SQL commands to perform data retrieval because it is derived from the
SqlDataSource
Despite its relative similarity to the SqlDataSource control, the AccessDataSource control has some
specialized parts First, the control does not require you to set aConnectionStringproperty Instead,
the control uses aDataFileproperty to allow you to directly specify the Access.mdbfile you want to use for data access
A side effect of not having theConnectionStringproperty is that the AccessDataSource cannot connect
to password-protected databases If you need to access a password-protected Access database, you can
use the SqlDataSource control, which allows you to provide the username and password as part of the
connection string.
Additionally, because the AccessDataSource uses the System.Data.OleDb to perform actual data access, the order of parameters matters You need to verify that the order of the parameters in any Select, Insert, Update, or Delete parameters collection matches the order of the parameters in the SQL statement
XmlDataSource Control
TheXmlDataSourcecontrol provides you with a simple way of binding XML documents, either
in-memory or located on a physical drive The control provides you with a number of properties that make
it easy to specify an XML file containing data and an XSLT transform file for converting the source
XML into a more suitable format You can also provide an XPath query to select only a certain subset
of data
You can use the XmlDataSource control’s Configure Data Wizard, shown in Figure 7-11, to configure
the control
Listing 7-14 shows how you might consume an RSS feed from the MSDN Web site, selecting all the item nodes within it for binding to a bound list control such as the GridView
Trang 4Figure 7-11
Listing 7-14: Using the XmlDataSource control to consume an RSS feed
<asp:XmlDataSource ID="XmlDataSource1" Runat="server"
DataFile="http://msdn.microsoft.com/rss.xml"
XPath="rss/channel/item"
</asp:XmlDataSource>
In addition to the declarative attributes you can use with the XmlDataSource, a number of other helpful
properties and events are available
Many times, your XML is not stored in a physical file, but rather is simply a string stored in your
appli-cation memory or possibly in a SQL database The control provides theDataproperty, which accepts a
simple string of XML to which the control can bind Note that if both theDataandDataFileproperties
are set, theDataFileproperty takes precedence over theDataproperty
Additionally, in certain scenarios, you may want to export the bound XML out of the XmlDataSource
control to other objects or even save any changes that have been made to the underlying XML if it
has been bound to a control such as a GridView The XmlDataSource control provides two methods
to accommodate this First, theGetXmlDocumentmethod allows you to export the XML by returning a
basicSystem.Xml.XmlDocumentobject that contains the XML loaded in the data source control
308
Trang 5Second, using the control’sSavemethod, you can persist changes made to the XmlDataSource control’s loaded XML back to disk Executing this method assumes you have provided a file path in theDataFile property
The XmlDataSource control also provides you with a number of specialized events TheTransforming
event that is raised before the XSLT transform specified in theTransformorTransformFileproperties is applied and allows you to supply custom arguments to the transform
ObjectDataSource Control
TheObjectDataSourcecontrol is one of the most interesting data source controls in the ASP.NET tool-box It gives you the power to bind data controls to middle-layer business objects that can be hard-coded
or automatically generated from programs such as Object Relational (O/R) mappers
To demonstrate how to use the ObjectDataSource control, create a class in the project that represents a
customer Listing 7-15 shows a class that you can use for this demonstration
Listing 7-15: Creating a Customer class to demonstrate the ObjectDataSource control
VB
Public Class Customer
Private _customerID As Integer
Private _companyName As String
Private _contactName As String
Private _contactTitle As String
Public Property CustomerID() As Integer
Get Return _customerID End Get
Set _customerID = value End Set
End Property
Public Property CompanyName() As Integer
Get Return _companyName End Get
Set _companyName = value End Set
End Property
Public Property ContactName() As Integer
Get Return _contactName End Get
Set _contactName = value End Set
Continued
Trang 6End Property
Public Property ContactTitle() As Integer
Get Return _contactTitle End Get
Set _contactTitle = value End Set
End Property
Public Function [Select](ByVal customerID As Integer) As System.Data.DataSet
’ You would implement logic here to retreive
’ Customer data based on the customerID parameter
Dim ds As New System.Data.DataSet() ds.Tables.Add(New System.Data.DataTable()) Return ds
End Function
Public Sub Insert(ByVal c As Customer)
’ Implement Insert logic End Sub
Public Sub Update(ByVal c As Customer)
’ Implement Update logic End Sub
Public Sub Delete(ByVal c As Customer)
’ Implement Delete logic End Sub
End Class
C#
public class Customer
{
private int _customerID;
private string _companyName;
private string _contactName;
private string _contactTitle;
public int CustomerID
{
get { return _customerID;
}
set { _customerID = value;
} }
Continued
310
Trang 7public string CompanyName
{
get
{
return _companyName;
}
set
{
_companyName = value;
}
}
public string ContactName
{
get
{
return _contactName;
}
set
{
_contactName = value;
}
}
public string ContactTitle
{
get
{
return _contactTitle;
}
set
{
_contactTitle = value;
}
}
public Customer()
{
}
public System.Data.DataSet Select(Int32 customerId)
{
// Implement logic here to retrieve the Customer
// data based on the methods customerId parameter
System.Data.DataSet ds = new System.Data.DataSet();
ds.Tables.Add(new System.Data.DataTable());
return ds;
}
Continued
Trang 8public void Insert(Customer c)
{
// Implement Insert logic }
public void Update(Customer c)
{
// Implement Update logic }
public void Delete(Customer c)
{
// Implement Delete logic }
}
To start using the ObjectDataSource, drag the control onto the designer surface Using the control’s smart
tag, load the Configuration Wizard by selecting the Configure Data Source option After the wizard
opens, it asks you to select the business object you want to use as your data source The drop-down list
shows all the classes located in theApp_Codefolder of your Web site that can be successfully compiled
In this case, you want to use theCustomerclass shown in Listing 7-8
Click the Next button, and the wizard asks you to specify which methods it should use for the CRUD
operations it can perform: SELECT, INSERT, UPDATE, and DELETE Each tab lets you select a specific
method located in your business class to perform the specific action Figure 7-12 shows that you want the
control to use a method calledSelect()to retrieve data
The methods the ObjectDataSource uses to perform CRUD operations must follow certain rules in
order for the control to understand For instance, the control’sSELECTmethod must return aDataSet,
DataReader, or a strongly typed collection Each of the control’s operation tabs explains what the control
expects of the method you specify for it to use Additionally, if a method does not conform to the rules
that specific operation expects, it is not listed in the drop-down list on that tab
Finally, if yourSELECTmethod contains parameters, the wizard lets you createSelectParametersyou
can use to provide the method parameter data
When you have completed configuring the ObjectDataSource, you should have code in your page source
like that shown in Listing 7-16
Listing 7-16: The ObjectDataSource code generated by the configuration wizard
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server" DeleteMethod="Delete"
InsertMethod="Insert" SelectMethod="Select" TypeName="Customer"
UpdateMethod="Update">
<SelectParameters>
<asp:QueryStringParameter Name="customerID" QueryStringField="ID"
Type="Int32" />
</SelectParameters>
</asp:ObjectDataSource>
As you can see, the wizard has generated the attributes for theSELECT,UPDATE,INSERT, andDELETE
methods you specified in the wizard Also notice that it has added theSelectparameter Depending
312
Trang 9on your application, you could change this to any of theParameterobjects discussed earlier, such as a
ControlParameterorQuerystringParameterobject
Figure 7-12
ObjectDataSource Events
The ObjectDataSource control exposes several useful events that you can hook into First, it includes
events that are raised before and after the control performs any of the CRUD actions, such as selecting or deleting events
It also includes pre- and post-events that are raised when the object that is serving as the data source
is created or disposed of, as well as when an event that is raised before a filter is applied to the data
All these events give you great power when you must react to the different ways the ObjectDataSource control behaves
Trang 10SiteMapDataSource Control
TheSiteMapDataSourceenables you to work with data stored in your Web site’s SiteMap configuration
file if you have one This can be useful if you are changing your site map data at runtime, perhaps based
on user privilege or status
Note two items regarding the SiteMapDataSource control First, it does not support any of the data
caching options that exist in the other data source controls provided (covered in the next section), so
you cannot natively cache your sitemap data Second, the SiteMapDataSource control does not have any
configuration wizards like the other data source controls This is because the SiteMap control can be
bound only to the SiteMap configuration data file of your Web site, so no other configuration is possible
Listing 7-17 shows an example of using the SiteMap control
Listing 7-17: Using the SiteMapDataSource control
<asp:SiteMapDataSource ID="SiteMapDataSource1" Runat="server" />
Using the SiteMapDataSource control is discussed in greater detail in Chapter 14
Configuring Data Source Control Caching
Caching is built into all the data source controls that ship with ASP.NET except the SiteMapDataSource
control This means that you can easily configure and control data caching using the same declarative
syn-tax All data source controls (except the SiteMapDataSource control) enable you to create basic caching
policies including a cache direction, expiration policies, and key dependencies
Remember that the SqlDataSource control’s caching features are available only if you have set the
DataSourceModeproperty toDataSet If it is set toDataReader, the control throws a
NotSupport-edException.
Cache duration can be set to a specific length of time, such as 3600 seconds (60 minutes), or you can set it
toInfiniteto force the cached data to never expire Listing 7-18 shows how you can easily add caching
features to a data source control
Listing 7-18: Enabling caching on a SqlDataSource control
<asp:SqlDataSource ID="SqlDataSource1" Runat="server"
SelectCommand="SELECT * FROM [Customers]"
ConnectionString="<%$ ConnectionStrings:AppConnectionString1 %>"
DataSourceMode="DataSet"
ConflictDetection="CompareAllValues"
EnableCaching="True" CacheKeyDependency="SomeKey" CacheDuration="Infinite">
<SelectParameters>
<asp:QueryStringParameter Name="CustomerID"
QueryStringField="id" Type="String"></asp:QueryStringParameter>
</SelectParameters>
</asp:SqlDataSource>
Some controls also extend this core set of caching features with additional caching functionality
specific to their data sources For instance, if you are using the SqlDataSource control, you can use the
314