dotNet - 2006 - 01
Transcript of dotNet - 2006 - 01
-
8/8/2019 dotNet - 2006 - 01
1/52W W . D O T N E T D E V E L O P E R S J O U R N A L . C
Presented by
THE WORLDS LEADING .NET RESOURTHE WORLDS LEADING .NET RESOUR
THE SHAPE OFi-TECHNOLOGY TO COME
2005 Volume3 Issue12
Create XML Easily with FOR XML PATHNew FOR XML features simplify XML creation
Creating Composite Server
Controls in ASP.NET 2.0Make new components from old
PresortedStandard
US PostagePAID
St. Croix Press
Coming...
March 13, 2006New York Citywww.ajaxseminar.com
Marriott Marquis
Times Square, NYC
SEEPAGE
25
FORDETAIL
S
Building a custom server control
The OO Database AdvantagePainless object-oriented databases
-
8/8/2019 dotNet - 2006 - 01
2/52
-
8/8/2019 dotNet - 2006 - 01
3/52
Want to accelerate resolution
of Web performance problems?
You can with WebLOAD Analyzerthe only load testing tool
with root cause analysis for .NET and Microsoft Web applications.
WebLOAD Analyzer employs unique black box software to
capture actual problems at multiple synchronized levels, enabling
users to drill down to the individual component. By pinpointing
the root cause of all kinds of application problems, WebLOAD
Analyzer reduces problem resolution time by 60%significantly
improving application performance and eliminating finger pointing
once and for all.
The Smart Choice in Web Application Testing RadView Software,Limited.All rights reserved.
Eliminate the finger pointing with WebLOAD Analyzer.0 0 0 1 0 1 1 0 1 0 0 0 1 0 1 1 0 1 0 0 1 0 1 0 1 0 1 0 1 0 0 0 1 0 1 1 0 1 0 0 1 0 1 0 1 0 1 1 0 1 0 0 0 1 0 1 1 0 1 0 0 0 1 1 1 0 1 0 0 1 0 1
0 0 0 1 0 1 1 0 1 0 0 0 1 0 1 1 0 1 0 0 1 0 1 0 1 0 1 0 1 0 0 0 1 0 1 1 0 1
1 0 1 0 1 1 0 1 0 0 0 1 0 1 1 0 1 0 0 0 1 1 1 0 1 0 0 1 0 1 0 1 0 1 0 1 1
Get a FREE No more finger pointing T-shirt. > > > > Learn more at www.radview.com/analyze
App Dev: It must be a database problem.
DBA: I suspect its your application server
code thats causing the problem.
-
8/8/2019 dotNet - 2006 - 01
4/524January 2006 dotnetdevelopersjournal.co
EDITORIAL
Five Development Tools I Wish I HadBy Derek Ferguson ...................................................................7
BOOK REVIEW
Amazon.com Top 10 .NET BooksProvided by Amazon.com........................................................8
SQL SERVER 2005
Create XML Easily with FOR XML PATHBy Jerry Dixon............................................................................22
PERFORMANCE
The OO Database AdvantageBy Rick Grehan and Eric Falsken ...........................................26
ASP.NET
When Design andDevelopment First MetBy Nina Meiers...........................................................................34
TIPS & TRICKS
DataWindow.NET How To:DataWindow FormattingBy Bruce Armstrong .................................................................42
BOOK REVIEW
.NET 2.0 GenericsBy Dennis Hayes .......................................................................48
MONO
Mono Releases Version 1.1.10and New RoadmapBy Dennis Hayes .......................................................................50
InsideDNDJ10
38
J a n u a r y 2 0 0 6 V o l u m e 4 I s s
30
MAKE NEW COMPONENTS FROM OLD
BY WES WEEKS
Creating Composite Server Controls
in ASP.NET 2.0
The Shape of i-Technologyto Come
BY JEREMY GEELAN
BUILDING A CUSTOM SERVER CONTROL
BY JEEVAN MURKOTH
Google Maps and ASP.NET
-
8/8/2019 dotNet - 2006 - 01
5/52
-
8/8/2019 dotNet - 2006 - 01
6/52
4
4
4
4
-
8/8/2019 dotNet - 2006 - 01
7/527dotnetdevelopersjournal.com January 2006
ve been doing a lot of cod-
ing lately. This has been a
bit of a departure from my
usual work as a technology
evangelist or a development manager,
but as you might imagine it has
been quite a lot of fun! Having said this,
the process of actually sitting down
and coding for 12 hours a day over the
past few months has left me wishing
that Visual Studio .NET shipped witha handful of additional capabilities in
the box.
Track Changes
If youve ever written a book oreven an article you have probably
encountered the track changes fea-
ture of Microsoft Word. By turning on
change tracking, every modification
that is made to a document is recorded
and a history of changes is kept. This
may sound a lot like source control and,
in fact, it is.
There are two important differ-
ences. The first is that, whereas source
control specializes in storing multiple
historical versions of a given document
at a central location where multiple
developers can access them via a check-
in/check-out process, change tracking
in Microsoft Word doesnt do any of this.It just stores additional metadata in a
single, local copy of a document.
The second difference which is
what I would like to see added to Visual
Studio to work in conjunction with
source control is the way in which
these historical changes are displayed.
By looking at a document in Word that
is under change control, I can instantly
see (via annotations in the margin) who
made changes to each bit of it, when
they changed it, etc. Wouldnt it be great
to be able to tell instantly by looking
at a piece of code who added a certain
line of it, and when? It would make it
so much easier to figure out whose
butt needed kicking when you see rank
stupidity.
Automated File Use Request
In keeping with the topic of sourcecontrol for a moment we have been
using Source Safe. There are quite afew of us on the team and we have not
(because it never works out right) turned
on multiple check-outs. This means
that I have to e-mail people two or three
times a day every day to ask them if I
could please use their files. Id like to be
able to ask Visual Studio to do this for
me, right off the dialog where it tells me
that a given file is currently in use.
Remote Desktop for Two Monitors
If you have two monitors at theoffice, drag some of your windows
(like Solution Explorer) onto your
second monitor, and then try to
Remote Desktop into your worksta-
tion when you get home. You will dis-
cover that Remote Desktop only gives
you access to your primary monitor
and that it is very hard to get back
the windows that are on your second
monitor.
Mock Environment Generator/
Automatic Expand-and-Collapse-All
for Solution Explorer
I lump these two together at the endbecause I am aware of third-party solu-
tions that do both of these things. Im
cheap, though so Id like it for free in
the box.
What tools would you like to see as a
part of Visual Studio .NET? Let me know
Editorial
EDITORIAL [email protected]
Editor-in-ChiefDerek Ferguson [email protected]
Executive EditorSeta Papazian [email protected]
Group PublisherJeremy Geelan [email protected]
Mobility EditorJon Box [email protected]
Security EditorPatrick Hynds [email protected]
Open Source EditorDennis Hayes [email protected]
Product Reviews EditorDoug Holland d [email protected]
VB EditorKeith Franklin [email protected]
Smart Client EditorTim Huckaby [email protected]
BizTalk EditorBrian Loesgen [email protected]
ADVISORY [email protected]
Derek Ferguson [email protected] Papazian [email protected]
Jeremy Geelan [email protected] Robbins [email protected] Gomez [email protected] Hanselman [email protected]
Dean Guida [email protected] Sharp [email protected]
Jacob Cynamon [email protected] Mayo [email protected] Cornell [email protected] Stagner [email protected] DeBetta [email protected]
EditorNancy Valentine n [email protected]
Online EditorRoger Strukhoff [email protected]
WRITERS IN THIS ISSUEBruce Armstrong, Jerry Dixon, Eric Falsken, Derek Ferguson,
Jeremy Geelan, Rick Grehan, Dennis Hayes, Nina Meiers,Jeevan Murkoth, Wes Weeks
SUBSCRIPTIONSFor subscriptions and requests for bulk orders,
please send your letters to Subscription Department
Subscription Hotline: [email protected] Price: $6.99/issueDomestic: $69.99/yr. (12 issues)
Canada/Mexico: $99.99/yr. Overseas: $129.99/yr.(U.S. banks or money orders). Back issues: $12/ea.,
plus shipping and handling.
EDITORIAL OFFICESSYS-CON Media 135 Chestnut Ridge Rd.,
Montvale, NJ 07645Telephone: 201 802-3000 Fax: 201 782-9638.NET Developers Journal (ISSN#1541-2849) is
published monthly (12 times a year) for $69.99 bySYS-CON Publications, Inc.,135 Chestnut Ridge Road,
Montvale, NJ 07645.Postmaster: Send address changes to:
.NET Developers Journal,SYS-CON Publications, Inc.,135 Chestnut Ridge Road
Montvale, NJ 07645
Copyright 2004 by SYS-CON Publications, Inc.All rights reserved. No part of this publication may be reproduced ortransmitted in any form or by any means, electronic or mechanical,including photocopy or any information storage and retrieval system,without written permission. For promotional reprints, contact ReprintCoordinator Dorothy Gil, [email protected].
Worldwide Newsstand DistributionCurtis Circulation Company, New Milford, NJ
Newsstand Distribution Consultant:Gregory Associates / W.R.D.S.732 607-9941 - [email protected]
For list rental information:Kevin Collopy: 845 731-2684,[email protected];Frank Cipolla: 845 731-3832,[email protected]
All brand and product names used on these pages are trade names,service marks, or trademarks of their respective companies. SYS-CONPublications, Inc., is not affiliated with the companies or productscovered in .NET Developers Journal. .NET and .NET-based marks aretrademarks or registered trademarks of Microsoft Corporation in the UnitedStates and other countries.
SYS-CON Publications, Inc., reserves the right to revise,
republish and authorize its readers to use the articlessubmitted for publication.
Five Development Tools
I Wish I Had BY DEREK FERGUSONEDITOR-IN-CHIEFAUTHOR BIO:
Derek Ferguson is an
associate director in the
Information Technology Group
at Bear Stearns, a leading global
investment banking, securities,
trading, and brokerage firm.
i
It would make it so much easier to figureout whose butt needed kicking when you
see rank stupidity
-
8/8/2019 dotNet - 2006 - 01
8/528January 2006 dotnetdevelopersjournal.co
Book Review
President and CEO
Fuat Kircaali [email protected]
President, SYS-CON Events
Grisha Davida [email protected]
Group Publisher
Jeremy Geelan [email protected]
ADVERTISINGSenior Vice President, Sales and Marketing
Carmen Gonzalez [email protected]
Vice President, Sales and Marketing
Miles Silverman [email protected]
Advertising Director
Robyn Forma [email protected]
Advertising Sales & Marketing Manager
Dennis Leavey [email protected]
Advertising Sales Manager
Megan Mussa [email protected]
Associate Sales Managers
Dorothy Gil [email protected]
Kim Hughes [email protected]
PRODUCTIONProduction Consultant
Jim Morgan [email protected]
Lead Designer
Tami Lima [email protected]
Art Director
Alex Botero [email protected]
Associate Art Directors
Louis F. Cuffari [email protected]
Andrea Boden [email protected]
Video Editor
Frank Moricco [email protected]
WEB SERVICESInformation Systems Consultant
Robert Diamond [email protected]
Web Designers
Stephen Kilmurray [email protected]
Shawn Slany [email protected]
Vincent Santaiti [email protected]
ACCOUNTINGFinancial Analyst
Joan LaRose [email protected]
Accounts Payable
Betty White [email protected]
Accounts Receivable
Gail Naples [email protected]
SYS-CON EVENTSPresident, SYS-CON Events
Grisha Davida [email protected]
National Sales Manager
Jim Hanchrow [email protected]
201 802-3012
888 303-5282
CUSTOMER RELATIONSCirculation Service Coordinators
Edna Earle Russell [email protected]
Linda Lipton [email protected]
JDJ Store Manager
Brunilda Staropoli [email protected]
Amazon.com Top 10 .NET Books
PROVIDED BY
MCAD/MCSD
Self-Paced
Training Kit:
Developing
Web
Applications
with Microsoft Visual Basic
.NET and Microsoft Visual C#
.NET, Second Edition
by Microsoft Corporation
Microsoft
Visual Basic
.NET Step byStep Version
2003
by Michael Halvorson
Applied
Microsoft .NET
Framework
Programming
by Jeffrey Richter
MCSD .NET
Solution
Architectures
Exam Cram 2
(Exam 70-300)
by Randy Cornish
Programming
ASP.NET
by Jesse Liberty
Developing
Application
Frameworks in
.NET
by Xin Chen
10MCAD/MCSD
Training Guide
(70-320):
Developing
XML Web
Services and
Server Components with
Visual C# .NET and the .NET
Framework
by Amit Kalani
MCAD/MCSD
Training Guide
(70-315):Developing
and
Implementing
Web Applications with Visual
C# and Visual Studio.NET
by Amit Kalani
Programming
Microsoft
Visual Basic
.NET Version
2003 (Book &
CD-ROM)
by Francesco Balena
9
8
7
5
4
2
6
3
MCAD/MCSD Self-Paced
Training Kit: Microsoft
.NET Core Requirements
by Microsoft Corporation1
-
8/8/2019 dotNet - 2006 - 01
9/52
W E H E L P Y O U D E L I V E R
T H E W H O L E P A C K A G E
V E R I O S U P P L I E S T H E B E S T T E C H N O L O G Y , R E S O U R C E A N D E X P E R T I S E T O S U P P O R T Y O U R . N E T S O L U T I O N
When you partner with Verio, you
deliver complete solutions for you
customers business needs. As you
trusted expert advisor for manage
hosting, we support your applicat
development with our managed
services and infrastructure from
state-of-the-art Verio data center
As a viaVerio partner, youll enha
your solutions portfolio and add v
to your business by gaining access
to our suite of global products an
services, including managed stora
and security. Youll also gain peac
of mind in knowing that Verio
is backed by the financial and
operational excellence of NTT
Communications, the world's large
telecommunications company.
BUILD YOUR BUSINESS BY
PARTNERING WITH THE MANAGE
HOSTING INFRASTRUCTURE EXPE
Nothing turns on the power of
the Internet like Verio products
and services.
CALL 866.237.4121 today to find
out more about how a viaVerio
partnership can complete yourbusiness offering. Or visit:
www.verio.com/partners
Power. Performance. Results.
Verio, viaVerio and the Verio logo are trademarks andservice marks of Verio Inc. in the United States and ocountries. All other names are trademarks or registeremarks of their respective owners. 2005 Verio Inc.All rights reserved.
-
8/8/2019 dotNet - 2006 - 01
10/5210January 2006 dotnetdevelopersjournal.co
am sure that most of
you have heard about or
have had a chance to use
Google Maps. Its a greatservice and I was really impressed
by the responsiveness of the appli-
cation and the ease with which
users could drag and zoom maps
from a Web browser. It has in many
ways heralded the arrival of AJAX
(Asynchronous JavaScript and XML),
which I am sure will revitalize Web
development in the days to come.
What makes the service even bet-
ter is the availability of the Google
Maps API (Application Programming
Interface) as a free Beta service. The
API allows developers to embed
Google Maps in their custom
applications. It also allows them to
overlay information on the map and
customize the map to their needs.
As I write this article there are quite
a few sites that utilize Google Maps,
and more and more of them are
appearing by the day.
The API by itself is pretty
straightforward and easy to use;
however, it requires the developer to
have a good command of JavaScript
because it extensively relies on cli-
ent-side Java scripting. In this article
we will be looking at building acustom ASP.NET server control that
would allow a .NET developer to
harness the power of Google Maps
in the code-behind model. We will
see how to accomplish most of the
functionality exposed by Google
Maps using this control, and well
also see how to data bind the con-
trol, thereby allowing developers to
easily build data-driven custom ASP.
NET Web applications. The control
would eliminate the need for the
developer to write any JavaScript to
accomplish most of the Google Map
functionality.
Some Google Maps Basics
Before we get into the details of
the ASP.NET control, lets look at the
basics of the Google Maps API. A
detailed description of the API can
be found at www.google.com/apis/
maps/documentation/ . The first
step before using Google Maps is to
register for a key with Google (www.
google.com/apis/maps/signup.
html). This is absolutely free and
hardly takes a few minutes. Each
Web site that uses Google Maps has
to have its own key. Make sure that
you go through Googles Terms of
Use (www.google.com/apis/maps/
terms.html) before you start using
Google Maps in your application.
Google represents an instance
of the map as a GMap object. It is
rendered as a div tag on the page.
Once you have the map, it is pos-
sible to add controls to the map.
Some of the available controls arethe GMapType control that helps to
toggle between the different views,
namely map view, satellite view,
and finally, the hybrid view that is
a combination of map and satel-
lite views. The other controls that
are usually seen on the map are
the ones used to add scrolling and
zooming capability to the map. At
the time of writing of this article,
there are three different controls
available:
GLargeMapControl: A large con-
trol for scrolling and zooming
GSmallMapControl: Similar to
the previous one, but eliminates
the zoom scale bar
GSmallZoomControl: Includes
only Zooming controls
Once the map has been set up, i
is possible to overlay information on
the map. The information can be in
the form of points or lines, though
points are the most common ones.
In order to overlay a point on the
Google Map, its necessary to know
its longitude and latitude. At this
time, Google does not provide anygeo-coding services that give the
co-ordinates corresponding to an
address, but there are a couple of
free services available on the inter-
net that do so. www.Geocoder.us is
one of them and given a US address
it returns the longitude and latitude
for the same. Once the longitude
and latitude have been obtained,
create an instance of a GPoint
(which is Googles representation
of a point on the map), then create
i
Building a custom server contro
BY JEEVAN MURKOTH
Figure 1: GMap control on the toolbar
in Visual Studio .NETf1
ASP.NET
Google Maps and ASP.NET
-
8/8/2019 dotNet - 2006 - 01
11/52
-
8/8/2019 dotNet - 2006 - 01
12/5212January 2006 dotnetdevelopersjournal.co
ASP.NET
a GMarker using this point and add
the marker to the instance of the
Google Map. In order to Center and
Zoom on a point, the GMap Object
exposes a method ZoomandCenter
that takes the point and the level of
zoom required as the parameter. Just
like points, it is possible to overlay
lines on the Map. Those of you who
have used Google Maps for direc-
tions will be familiar with the lines
used to depict the route. In order
to add a line to the Google Map,
we need to create an instance of
a GPolyLine object and pass in an
array of GPoints to plot it. It is also
possible to assign color, width, and
opacity to the line. Another useful
feature in Google Maps is the abilityto show a pop-up window when the
user clicks on a Marker. Google Calls
this pop-up window by the name
InfoWindow.
The Google Maps ASP.NET
Control (GMAP Control)
The main aim of this control is
to allow .NET developers to utilize
the functionality of Google maps as
a server-side control by writing little
to almost no JavaScript at all. It is
more of a .NET wrapper around the
Google API; however, because it is
a full-fledged ASP.NET server-side
control, it is possible to bind data
to the control, thereby increasing
the usability of Google Maps. In the
following sections we will see how
to use this control to implement
most of the common functionality
of Google Maps. Before we do so,
lets take a look at the control. The
principal class of the control is the
GMapControl class. This class in
turn references the following classes
(most of these classes are the .NET
equivalents of the classes used by
Google):
GPoint: This is the class represen-
tation of a geographical point andexposes latitude and longitude as
its two properties.
GPoints: This class represents a
collection of GPoint objects.
GIcon: Represents a custom
icon that is used as an overlay
on the map. The GIcon class
exposes the following proper-
ties: the Image URL, which as the
name suggests, is the URL of the
image used to represent the icon;
ShadowImageURL is the URL of
the shadow associated with the
icon; IconSize and ShadowSize
represent the size of the icon
and the shadow, and the last two
properties are IconAnchor and
InfoWindowAnchor, which specif
the point where the icon should
be anchored to the map relative
to its top-left corner and the poin
where the Info window should be
anchored to the map.
GLine: This is a line that the user
wishes to overlay on the map.
By default it takes a collection
of points (GPoints) as an argu-
ment in its constructor. It is also
possible to set the color of the
line as well as its weight and
opacity through an overloadedconstructor.
GMarker: This is the .NET repre-
sentation of the Google Maps clas
GMarker. The default constructor
accepts an instance of a GPoint
class. It also has an overloaded
constructor that takes a GIcon
along with the GPoint in case the
developer wishes to use a custom
icon to represent the marker.
GSize: Represents a two-dimen-
sional size measurement.
Figure 2: Output in the Web browser for Listing 2f2 Figure 3: Output in the Web browser for Listing 3f3
-
8/8/2019 dotNet - 2006 - 01
13/52
-
8/8/2019 dotNet - 2006 - 01
14/5214January 2006 dotnetdevelopersjournal.co
ASP.NET
JScriptGenerator: This is an inter-
nal class and has more of a helper
function. It generates most of
the JavaScript functions that are
needed by the control.
HelperColorConvertor: This class
is used to convert a color into its
equivalent Hex value. This class is
marked as internal.
HelperDataResolver: This is an
internal class that helps in data
binding and has just one method.
The method casts a datasource
object into an object that imple-
ments the IEnumerable interface.
The help file that describes in
detail the different methods and
properties of the classes involved
is available as a download.
Getting Started in ASP.NET
Before we use the ASP.NET con-
trol in our application, there are a
few things that need to be taken
care of to ensure that it works as
desired.
Web.config File
The GMAP control renders itself
as a DIV tag, however for non
Internet Explorer Browsers, ASP.
NET renders the div tag as tables. If
you want the page to render the
GMAP control properly in other
browsers such as Netscape and
Firefox, include the browser cap
section shown in Listing 1 into
the Web.config file of your
application.
Page Configuration
Google has certain recommen-
dations for the HTML standards
on pages that contain the map to
make sure that the layout is pre-
dictable across different browsers.
A detailed description of the same
can be found in the Google maps
documentation. It is imperative
that you follow these standards,
especially if you plan to overlay
lines on your map. For lines to berendered on the map, you need to
include the VML namespace in the
HTML page for Internet Explorer
browsers. Make sure that you dont
forget to do this, because otherwise
the lines will not be displayed in
Internet Explorer. The HTML tag of
your page should at the minimum
look like the snippet below:
Adding to the Toolbar
This step is optional; however if
you are using Visual Studio .NET as
your IDE, I would recommend that
you go ahead and add the GMap
control to your toolbox. The advan-
tage of doing so is that you can easil
drag and drop the GMap control
onto an ASPX page like any other
ASP.NET control, and Visual Studio
will automatically register the con-
trol on your page. Figure 1 shows th
GMap control on the toolbar.
Creating a Basic Map Using
the Control
Since we are done with the setup
lets go ahead and create a simple
example using the control. We will
add the GMap control to the page,set its dimensions, and make it cen-
ter and zoom at a particular point.
For the sample application used in
this article, I have saved the map key
in the Web.config file and will be set
ting the GoogleMapKey property of
the control from the config file. I wil
be setting the map type of the con-
trol to be that that of Map. In case
no map type is specified, the contro
defaults to the preset Map. The
GMap Control also supports satellit
Figure 4: Output in the Web browser for Listing 4f4 Figure 5: Output showing the custom markersf5
-
8/8/2019 dotNet - 2006 - 01
15/52
Security should never be an inhibitor to new opportunity: Forum XWall Web Services
Firewall has been enabling Fortune 1000 companies to move forward with XML Web
services confidently. Forum XWall regulates the flow of XML data, prevents unwanted
intrusions and controls access to critical Web services.
Visit us at www.forumsys.com to learn more about how you can take your next leap
forward without increasing the risks to your business.
forum systems the leader in web services security
Forum XWall Web Services Firewall - Reinventing Security
None of the Risk.
XMLs Endless Possibilities,
-
8/8/2019 dotNet - 2006 - 01
16/5216January 2006 dotnetdevelopersjournal.co
and hybrid map types. Make sure
that you center and zoom at a point,
otherwise all that will show up will
be a grey area. Listing 2 shows the
code for this example and Figure 2
shows the output.
Setting the GMap Control
Properties
Lets go ahead and set some
properties to the basic example
we just created. The GMap control
exposes a set of properties that
allows the developer to customize
the control to his or her needs. If
we wish to give the user the flex-
ibility to change the view, we set
the ShowMapTypeControl property
of the control to true. By default,
the user is able to drag the map,however, if we do not wish the
user to drag the map around, we
can set the EnableDragging prop-
erty to false. To allow the user to
be able to scroll or zoom, set the
ScrollControlType property of the
control. There are three different
options: large, small, and zoom
only, to correspond to the controls
offered by Google. Listing 3 shows
the source code and Figure 3 shows
the output in the browser.
Overlaying Markers and Pop-Up
Windows
Another cool feature of Google
Maps is the ability to display mark-
ers on the map and attach pop-up
windows to these markers on the
click event. It is possible to dis-
play formatted HTML containing
links and images in these pop-up
windows. Let us see how to do
the same using the GMap ASP.
NET control. Lets take the previ-
ous example and modify it to add
two markers. One would be a plain
marker and the other would have
a pop-up window that would dis-
play some text. The GMap ASP.NET
control has an overloaded method
called OverlayMarker that takes the
formatted HTML as a string param-eter. If the overloaded method is
called and some HTML is passed
to the method, a click event is
automatically passed to the marker
and the info window is displayed.
Listing 4 shows the code to overlay
two markers and Figure 4 shows the
output of the same.
Overlaying Custom Markers
Google gives us the flexibility
to replace their standard marker
icon with any custom icon that we
specify. The same functionality is
provided by the GMap ASP.NET con
trol. In order to do so, we need to
define a GIcon class with at least th
following properties:
URL of the image that would rep
resent the GIcon
URL of the shadow image
Size of the image
Size of the shadow
The point at which the icon is to
be anchored to the icon
In case info windows are used,
it is also necessary to specify the
point where the info window is to
be anchored to the map. For this
example we will be borrowing the
icons from the Google Ride Finderapplication. Lets take the same two
points that we used in the marker
example and replace the standard
marker icons with these custom
icons. The code in Listing 5 is same
as that of Listing 4, except for the
use of custom icons. Figure 5 shows
the output.
Overlaying Lines
In this section we will see how
to overlay a line on a Google Map.
ASP.NET
Figure 6: Rendering of the line in the browserf6 Figure 7: Multiple Google Map controls outputf7
-
8/8/2019 dotNet - 2006 - 01
17/52
-
8/8/2019 dotNet - 2006 - 01
18/5218January 2006 dotnetdevelopersjournal.co
Lines can be overlaid on maps to
denote routes, boundaries, or some
other specific purpose a developer
may deem necessary. As in the
Google Maps API, the GMap ASP.
NET control also allows overlay
of lines. In the GMap control, the
GLine class represents a line and
takes a collection of GPoints to plot
a line through them. It is also pos-
sible to set the color, width, and
opacity of the line. While the Google
Maps API requires color to be
passed in as a Hex value, the GMap
control takes in a System.Drawing.
Color structure, thereby making
it easier to set the color by name.
Listing 6 shows the code and Figure6 shows the rendering.
Using Multiple Google Map
Controls in a Page
So far in all of the examples, we
have dealt with one instance of the
control in a page. It is possible to
have any number of GMap controls
in a single page and have granular
control over each one of them. In
this example, we have four instanc-
es of the control and will center and
zoom them on four different cities.
Listing 7 shows the code and Figure7 shows the output in the browser. It
is possible to have markers or lines
on any of these controls.
Binding Data to the Control
The GMap ASP.NET control sup-
ports data binding and it is possible
to bind it to any data source that
implements the IEnumerable inter-
face, hence it can bind to most of
the commonly used sources such as
data tables, datasets, and collections.
As of now the control only supports
overlaying of standard markers via
data binding. The control exposes
the following properties that need to
be set before data binding:
MarkerLatitudeField: Property
used to specify which field from
the data source will bind to the
latitude field of each marker in th
control
MarkerLongitudeField: Property
used to specify which field from
the data source will bind to thelongitude field of each marker in
the control
MarkerText: Property used to
specify which field from the data
source will bind to the Text field o
each marker in the control (this is
optional)
DataSource: Property used to set
the source of data
In this example we will first
populate a table with a point and
then bind it to the GMap control.
Listing 8 shows the code involved inthe example and Figure 8 shows the
output.
Conclusion
The Google Maps API is very ver-
satile. I hope this control will make it
easier for .NET developers to harness
the potential of this API.
References
Google Maps API documentation
www.google.com/apis/maps/
documentation/
Google Maps news groups: www.
google.com/apis/maps/
documentation/
Onion, F. (2003). Essential ASP.
NET (Custom Controls). Addison-
Wesley Professional.
ASP.NET
Figure 8: Output from Listing 8f8
Listing 1: Browser Cap Section
browser=Netscape
frames=true
tables=true
cookies=true
javascript=true
javaapplets=true
cmascriptversion=1.5
w3cdomversion=1.0
css1=true
css2=true
xml=true
tagwriter=System.Web.UI.HtmlTextWriter
version=6.0
majorversion=6
minorversion=0
beta=true
version=7.0
majorversion=7
minorversion=0
beta=true
-
8/8/2019 dotNet - 2006 - 01
19/5219dotnetdevelopersjournal.com January 2006
Listing 2: Basic Map
privatevoid Page_Load(object sender, System.
EventArgs e)
{GMapControl1.Width=400;
GMapControl1.Height=400;
GMapControl1.MapType=MapControl.GMapType.MAP;
GMapControl1.GoogleMapKey=Configuration-
Settings.AppSettings[DevKey];
GMapControl1.CenterAndZoom
(new GPoint(36.224264,-86.628273),9);
}
Listing 3: Setting Properties
privatevoid Page_Load(object sender, System.
EventArgs e)
{
GMapControl1.Width=400;
GMapControl1.Height=400;
GMapControl1.MapType=MapControl.GMapType.MAP;
GMapControl1.ScrollControlType=MapControl.
GMapScrollControl.LARGE ;
GMapControl1.EnableDragging=false;
GMapControl1.ShowMapTypeControl=true;
GMapControl1.GoogleMapKey=Configuration-
Settings.AppSettings[DevKey];
GMapControl1.CenterAndZoom
(new GPoint(36.224264,-86.628273),9);
}
Listing 4: Overlaying Markers
privatevoid Page_Load(object sender, System.
EventArgs e)
{
GMapControl1.Width=400;
GMapControl1.Height=400;
GMapControl1.MapType=MapControl.GMapType.MAP;
GMapControl1.ScrollControlType=MapControl.
GMapScrollControl.LARGE ;
GMapControl1.ShowMapTypeControl=true;
GMapControl1.GoogleMapKey=Configuration-
Settings.AppSettings[DevKey];
GPoint myPoint= new GPoint(36.1645,-86.7811);
GPoint myPoint2= new GPoint(36.224264,-
85.928273);string sFormattedHtml=Nashville
Visit Nashville ;GMarker myMarker= new GMarker(myPoint);
GMarker myMarker2= new GMarker(myPoint2);
//Overloaded constructor
GMapControl1.OverlayMarker(myMarker,sFormatted
Html);
GMapControl1.OverlayMarker(myMarker2);
GMapControl1.CenterAndZoom(myPoint,9);
}
Listing 5: Custom Markers
privatevoid Page_Load(object sender, System.
EventArgs e)
{
GMapControl1.Width=400;
GMapControl1.Height=400;
GMapControl1.MapType=MapControl.GMapType.MAP;
GMapControl1.ScrollControlType=MapControl.
GMapScrollControl.LARGE ;
GMapControl1.ShowMapTypeControl=true;
GMapControl1.GoogleMapKey=Configuration-
Settings.AppSettings[DevKey];
GPoint myPoint= new GPoint(36.1645,-86.7811);
GPoint myPoint2= new GPoint(36.224264,-
85.928273);
string sFormattedHtml=
Nashville
VisitNashville ;
GMarker myMarker= new GMarker(myPoint);
//Creating our custom icon
GIcon myIcon = new GIcon();
myIcon.ImageURL=http://labs.google.com/
ridefinder/images/mm_20_blue.png;
myIcon.ShadowImageURL=http://labs.google.com/
ridefinder/images/mm_20_shadow.png;
myIcon.ShadowSize= new GSize(22,20);
myIcon.IconSize = new GSize(12,20);
myIcon.IconAnchor= new GPoint(6,20);
myIcon.InfoWindowAnchor= new GPoint(5,1);
GMarker myMarker2= new GMarker(myPoint2);
myMarker.Icon=myIcon;
GMapControl1.OverlayMarker(myMarker,sFormatted
Html);
myMarker2.Icon=myIcon; myMarker2.Icon.
ImageURL=http://labs.google.com/ridefinder/
images/mm_20_green.png;
GMapControl1.OverlayMarker(myMarker2);GMapControl1.CenterAndZoom(myPoint,9);
}
Listing 6: Overlaying Lines
privatevoid Page_Load(object sender, System.
EventArgs e)
{
GMapControl1.Width=400;
GMapControl1.Height=400;
GMapControl1.MapType=MapControl.
-
8/8/2019 dotNet - 2006 - 01
20/5220January 2006 dotnetdevelopersjournal.co
ASP.NET
GMapType.MAP;
GMapControl1.ScrollControlType=
MapControl.GMapScrollControl.LARGE ;
GMapControl1.ShowMapTypeControl=true;
GMapControl1.GoogleMapKey=Configura-
tionSettings.AppSettings[DevKey];
// Creating the 3 points through which
the line passes
GPoint pt1 = new GPoint(40.631096,-
75.488627);
GPoint pt2= new GPoint(35.113813,-
85.321043);
GPoint pt3= new GPoint(33.590040,-
101.866815);
//Adding it to the points collections
GPoints ptList= new GPoints();
//Adding it to the points collections
ptList.Add(pt1);
ptList.Add(pt2);
ptList.Add(pt3);
//Adding the points collection to the
line
GLine myline = new GLine(ptList);
//Setting the Color , weight and
Opacity
myline.LineColor=Color.Blue;
myline.Weight =3;
myline.Opacity=1;
GMapControl1.OverlayLine(myline);
GMapControl1.CenterAndZoom(pt2,14);
}
Listing 7: Multiple Controls in a Page
privatevoid Page_Load(object sender, System.
EventArgs e)
{
//First Control
GMapControl1.Width=200;
GMapControl1.Height=200; GMapControl1.
GoogleMapKey=ConfigurationSettings.
AppSettings[DevKey];
GMapControl1.CenterAndZoom(new GPoint
(36.224264,-86.628273),9); //Second Control
GMapControl2.Width=200;
GMapControl2.Height=200; GMapControl2.
GoogleMapKey=ConfigurationSettings.
AppSettings[DevKey];
GMapControl2.CenterAndZoom
(new GPoint(35.07,-85.27),9);
//Third Control
GMapControl3.Width=200;
GMapControl3.Height=200; GMapControl3.
GoogleMapKey=ConfigurationSettings.
AppSettings[DevKey];
GMapControl3.CenterAndZoom(new GPoint
(30.32,-97.77),9);
//Fourth ControlGMapControl4.Width=200;
GMapControl4.Height=200; GMapControl4.
GoogleMapKey=ConfigurationSettings.
AppSettings[DevKey];
GMapControl4.CenterAndZoom
(new GPoint(39.57,-75.10),9);
}
Listing 8: Data Binding in GMap Control
privatevoid Page_Load(object sender, System.
EventArgs e)
{
GMapControl1.Width=400;GMapControl1.Height=400;
//create the datatable
DataTable dt = new
DataTable(Databind);
dt.Columns.Add( new DataColumn
(latitude,typeof(double)));
dt.Columns.Add( new DataColumn
(longitude,typeof(double)));
dt.Columns.Add( new DataColumn
(htmltext,typeof(string)));
//Filling the datatable
for( int i=0; i
-
8/8/2019 dotNet - 2006 - 01
21/52
-
8/8/2019 dotNet - 2006 - 01
22/5222January 2006 dotnetdevelopersjournal.co
BY JERRY DIXON
SQL Server 2005
Create XML Easily with FOR XML PATH
o you love XML? Have
you been using XML with
SQL Server? Many people
have, starting way back
when with SQL Server 7.0. Back then,
there was no support for XML in the
database, so we had to write external
programs to convert the relational
data into an XML format. This was
time-consuming and often inef-
ficient. When SQL Server 2000 came
out, with its integrated support for
XML, there were a lot of high expec-tations. Unfortunately, XML still
couldnt be easily stored in the data-
base, although it could be created
and consumed. XML couldbe stored
in the database as a large string of
text, but this was problematic at
best. Large VARCHAR and TEXT
strings are hard to manipulate. This
worked, though, and programmers
managed to create great systems.
Still, something more was needed.
Many people looked forward to
the next version of SQL Server, and
hoped for a better solution.
SQL Server 2005 is now here, and
with it comes a new XML data type
and support for the new XQuery
language. XML can now be stored
directly in the database, queried, and
even edited in place. In addition,
the existing creation and consump-
tion capabilities from SQL 2000 have
been enhanced. XML can be created
and consumed much more easily
than ever before. With all of these
enhancements, how should one pro-
ceed?
Last year, I couldnt wait for the
ability to store XML in the database.I was sure that this capability would
be the answer to all of my XML-relat-
ed problems. Because SQL Server
2005 now has an XML data type, we
can store entire documents directly
in a column of a table. I was posi-
tive that this would be the first new
feature that I would use. However,
an unexpected thing occurred along
the way: Microsoft enhanced the
FOR XML clause. It is much easier to
create XML from relational data than
it ever was before. Ive found that
I havent been using the XML data
type nearly as often as I expected.
Instead, Ive been storing data
relationally, creating the XML as
needed. I believe that this gives my
applications the best features of both
worlds. Therefore, I wish to pass this
information on to you.
This article will introduce some
of the new XML-creation features in
SQL Server 2005 and provide some
guidance regarding their use. It willdemonstrate how much easier it is
to create XML in SQL Server 2005
that it ever was in SQL Server 2000.
Well walk through the creation of a
small XML document and discuss
each step in detail. Because of space
limitations, the XML data type and
the related XQuery language will be
covered in a future column.
FOR XML EXPLICIT Refresher
In order to fully appreciate the
new SQL Server 2005 features, you
must first understand the difficulties
faced by SQL Server 2000 develop-
ers. These are best illustrated with an
example. Lets examine a simple XML
document that I created from data in
the new AdventureWorks database
(see Listing 1). The document has
a single root element that contains
multiple Category elements. These
elements, in turn, contain multiple
SubCategory elements. (Ellipses
are used to indicate sections where
similar elements have been removed
for space reasons.) The Category and
SubCategory elements each have a
Name attribute. This small, straight-
forward document is complex enoug
for our purposes.
In Listing 2, Ive created a FOR
XML EXPLICIT query that creates
the demonstration document. This
query is representative of those com-monly created with SQL Server 2000.
Notice that there are three individual
SELECT statements joined together
via UNION ALL clauses. Each SELEC
statement corresponds to a node in
the resulting XML document. Each
column in the SELECT statements is
named according to a special scheme
which helps define the structure of
the resulting document. There are
also columns (Tag and Parent)
that exist for no other purpose than
to define the document schema. To
make matters worse, the ORDER BY
clause must be carefully designed
in order to make the resulting docu-
ment nest properly. While this proces
works, with larger documents it can
quickly become too complex to be
practical. In addition, because of the
fact that it is based on UNION claus-
es, it is highly repetitive. Maintenanc
of such queries can become very diff
cult. (I once created such a query wit
12 individual SELECT statements.
What a nightmare that was!)
FOR XML Enhancements
SQL Server 2005 has a solutionto these shortcomings. There is a
new PATH directive in the FOR XML
clause. This directive allows much of
the structure, or schema, of the resul
ing XML document to be specified
via XPath. Take the code in Listing 3
for example. The SELECT statement
returns a single column whose alias
is an XPath expression. The expres-
sion indicates that the column result
should become an attribute called
Name. (In XPath, the @ symbol
d
New FOR XML features simplify XML creation
-
8/8/2019 dotNet - 2006 - 01
23/5223dotnetdevelopersjournal.com January 2006
indicates an attribute. The lack of this
symbol indicates an element. See an
XPath reference for more information.)
When executed, this code will create
the XML document shown in Listing
4. As you can see, this creates an ele-ment for each row, with the attribute
name that we specified; however, each
element is named row. This is prob-
ably not what we would want in our
actual document. Fortunately, there is
a solution for this too. In Listing 5, Ive
altered the SELECT statement so that
the resulting elements will be named
Category. The results are shown in
Listing 6.
If you glance back at Listing 1,
youll notice that weve managed to
reproduce the Category elements
contained in that document. Next,well need to write some code for the
SubCategory elements. This code,
along with its results, is shown in
Listing 7. This SELECT statement is
very similar to the one for the Category
elements, except that the data is
retrieved from a different table and
the results get placed in different ele-
ments.
Now that we have the data for both
sets of elements, we need a way to
combine them together appropriately.
The new TYPE directive can be used for
this. The TYPE directive specifies that
the XML created in a FOR XML query
should be returned as an instance of
the XML data type. The data can then
be stored in an XML variable, placed in
an XML column in a table, or further
manipulated in T-SQL statements. It
is this last capability that we will use.
With the TYPE directive, we now have
the ability to nest FOR XML PATH que-
ries. This allows us to create XML docu-ments of almost any depth. You can see
this technique in use in Listing 8. Ive
combined the queries for the Category
and SubCategory elements, linking
them together with an appropriate
WHERE clause. The XML produced is
shown in Listing 9.
Although the XML document is
now well formed and properly nested,
it is not yet valid. XML documents
should have only one root element.
If you look at our document, youll
see that we have four instances of the
Category element, all at the root level.We need to change our last query so
that it produces one root element and
includes the Category elements under-
neath this new root. To do this, we can
take advantage of one final enhance-
ment. The FOR XML clause now has a
ROOT directive, which indicates that
a root element should be created for
us. By default, this root element will be
given the name root. If we so desire,
we can also specify the name of this
root element. In Listing 10 you can see
the query with this directive added.
The final XML document is shown in
Listing 11.
Weve now come full circle. If you
compare Listing 1 (produced with FOR
XML EXPLICIT) and Listing 11 (pro-
duced with FOR XML PATH), youll
see that they are identical. However,
the new syntax is much cleaner and
easier to create (compare Listings 2
and 10 to see this). The performance
of the two implementations is similar,although the execution plan for the
FOR XML PATH query is noticeably
smaller. Because of this, FOR XML
PATH queries should edge out FOR
XML EXPLICIT queries when larger
or more complicated documents are
created. When you factor in readability
and maintenance, the new method
wins hands down.
Summary
When I started using the XML
support in SQL Server 2005, I fully
expected that I would be storing datainside tables as XML. I thought that
this would be the easiest way to send
XML to applications outside the server.
As Ive learned more about the prod-
uct, I have seen how the improved
FOR XML clause makes the creation of
XML documents easier to accomplish
and maintain. This has changed my
perceptions. With the new FOR XML
PATH clause, we can store our data
relationally and easily produce the
XML when needed. In this way, we can
take advantage of the capabilities of
both data formats. We can use the rela-
tional data in a JOIN, for example, and
produce the XML whenever necessary.
With SQL Server 2005, the choice is
now ours.
Listing 1: XML Document
...
...
...
Listing 2: SQL 2000 FOR XML EXPLICIT
SELECT
1 AS Tag,NULL AS Parent
,NULL AS XML!1
,NULL AS Category!2!Name
,NULL AS SubCategory!3!Name
UNION ALL
SELECT DISTINCT
2 AS Tag
,1 AS Parent
,NULL AS XML!1
,Name AS Category!2!Name
,NULL AS SubCategory!3!Name
AUTHOR BIO:
Jerry Dixon is a senior devel-
oper and architect for ACH
Food Companies in Memphis,
Tennessee. Over the past 16 year
he has led development projects
for a number of enterprise, mid-
level, and small business organiza
tions. While he has fulfilled multiple
roles as an infrastructure designer
database administrator, and soft-
ware developer, he specializes in
XML, SQL and ASP.NET. He is a
co-leader and frequent presenter
at the Memphis .NET User Group
Jerry holds the following Microsoft
certifications: MCSD (VB 6.0
and .NET), MCDBA (SQL 2000),
MCSA (Windows 2000 and 2003)
MCSE (Windows 2000), MCAD(.NET), MCT. He resides in Olive
Branch, MS with his wife and son
-
8/8/2019 dotNet - 2006 - 01
24/5224January 2006 dotnetdevelopersjournal.co
SQL Server 2005
FROM Production.ProductCategory
UNION ALL
SELECT
3 AS Tag,2 AS Parent
,NULL AS XML!1
,c.Name AS Category!2!Name
,sc.Name AS SubCategory!3!Name
FROM Production.ProductCategory c
INNER JOIN Production.
ProductSubCategory sc
ON c.ProductCategoryID =
sc.ProductCategoryID
ORDER BY
Category!2!Name
,SubCategory!3!Name
FOR XML EXPLICIT
Listing 3: FOR XML PATH
SELECT Name AS @Name
FROM Production.ProductCategory
FOR XML PATH
Listing 4: FOR XML PATH Results
Listing 5: Named Element
SELECT Name AS @Name
FROM Production.ProductCategory
FOR XML PATH(Category)
Listing 6: Named Element Results
Listing 7: SubCategory Example
SELECT Name AS @Name
FROM Production.ProductSubCategory
FOR XML PATH(SubCategory)
...
Listing 8: Combining the Queries
SELECT c.Name AS @Name,
(SELECT sc.Name AS @Name
FROM Production.ProductSubCategory sc
WHERE sc.ProductCategoryID =
c.ProductCategoryID
FOR XML PATH(SubCategory), TYPE)
FROM Production.ProductCategory c
FOR XML PATH(Category)
Listing 9: Combined Results
...
...
...
Listing 10: Adding a Root Element
SELECT c.Name AS @Name,
(SELECT sc.Name AS @Name
FROM Production.ProductSubCategory sc
WHERE sc.ProductCategoryID =
c.ProductCategoryID
ORDER BY sc.Name
FOR XML PATH(SubCategory), TYPE)
FROM Production.ProductCategory c
ORDER BY c.Name
FOR XML PATH(Category), ROOT(XML)
Listing 11: Final Results
...
...
...
-
8/8/2019 dotNet - 2006 - 01
25/52
RIGHT 2006 SYS-CON MEDIA ALL RIGHTS RESERVED NOTE: SPEAKER LINE-UP SUBJECT TO CHANGE WITHOUT NOTICE
23
-
8/8/2019 dotNet - 2006 - 01
26/5226January 2006 dotnetdevelopersjournal.co
Performance
The OO Database AdvantagePainless object-oriented databases
BY RICK GREHAN
eres a question: If you write
your applications code in
an OO language such as
C#, VB.NET, or managed
C++ why not write database query
and update code in the same language?
It would certainly make life simpler,
wouldnt it? At the very least, youd only
have to hold one language in your head
not your programming language and
SQL.
Thats the very least of the advan-
tages youd gain by choosing an OOdatabase instead of an RDBMS. The
metaphor impedance mismatch
has frequently been used to illustrate
the problems that arise from using a
relational database as the back end to
an OO application. Admittedly, its a
somewhat overused metaphor, but it
still serves its purpose. It illustrates the
fact that relationships among objects
referencing, containment, polymor-
phism, and so on must be translated
into relational constructs when those
objects are stored in the database.
Furthermore, the translations require
developer intervention at some point:
either explicitly in executable code, by
creating schema mapping files that a
translation layer reads and interprets, or
through some other mechanism.
The upshot is that you have to
explain the object structure of your
application to a relational database
and in terms that the relational data-
base understands. Sometimes this even
requires you to add elements to one or
more of your objects elements that
translate to additional columns in one
of the RDBMS tables, and serve no
purpose other than to support objectrelationships.
Specifically, suppose you have an
OO application whose objects struc-
tures exhibit a tree-like or networked
arrangement. With regard to entities
that your program can treat as a single
(albeit complex) object, the back-end
RDBMS must distribute across multiple
rows and (likely) multiple tables. For
example, deleting a single tree which
in OO code would be the mere drop-
ping of a reference turns into multiple
delete operations on multiple tables.
(Source code for this article is avail-
able from www.everylittlething.net/
PartsAssembly/.)
Illustration by Example
Suppose you must write an applica-
tion for an assemblies database that
is, a database whose content tracks
items that are assembled from parts.
A part. in this case, could be just
about anything: a screw, a light bulb, a
spring, or even a software component.It doesnt really matter: the idea is that
assemblies are constructed by connect-
ing parts together, and in turn, more
complex assemblies can be fabricated
by connecting assemblies together.
The aggregation of lower-level
assemblies continues until a top-level
assembly (or a finished product)
is reached. Therefore for example, a
motherboard assembly consisting of
circuit board, CPU, and memorypart
objects is combined with a power-
supply assembly, a disk-drive assembly,
and a chassis assembly to create a desk-
top system. This structure is illustrated
in Figure 1.
This kind of database is nicely
portrayed in an object-oriented struc-
ture. The Part class is the fundamental
building block. From it, one derives a
PartAssembly class (which models an
Assembly from Figure 1, but which we
renamed in order to sidestep any con-
fusion with .NETs meaning of the word
assembly). The PartAssembly class
extends the Part class by adding an
ArrayList collection of components.
Members of the components col-
lection are required to assemble this
PartAssembly.
If we strip away the method defini-
tions for these classes, the structure
becomes transparently obvious (see
Listing 1). When implemented in a
relational database, the class structure
in Listing 1 would require two or three
tables, depending on how a person
modeled the inheritance relation.
In a three-table arrangement, Partobjects would be stored in one table,
PartAssembly objects in a second,
and the contents of the components
ArrayList in a third. (This kind of map-
ping from OO to relational is referred t
as horizontal mapping.) The column
structure of the Part and PartAssembly
tables would be identical, because the
only difference between the two the
components element in PartAssembly
would be stored in the third table. Th
components dictionary table would
hold two columns, one for the Part, an
a second to reference the PartAssembly
identifier. This second column is a for-
eign key, and provides the connection
between the components and their
owning PartAssembly object.
In a two-table solution, Part and
PartAssembly would share the same
table (this is known as filtered map-
ping). That table would include
columns for category, name, manufac-
turer, and manufacturerPartNumber.
An extra column would be added cal
it classID that would be used to dis-
tinguish rows that correspond to Part
objects from rows that correspond to
PartAssembly objects.The advantage of the three-table
mapping strategy is its conceptual sim
plicity. Each concrete class gets its own
table. It is also more easily extended. If
for example, a new class were defined
that extended PartAssembly, the devel
oper would need only to construct a
new table.
On the other hand, the two-table
strategy has the advantage of minimiz-
ing the number of tables required.
However, adding a new descendant
i
AND ERIC FALSKEN
Assembly
Assembly Assembly
Part Part Part Part Part
Figure 1: The structure of the
assembly database fits nicely into
object-oriented grooves. Parts
belong to assemblies, and both are
derived from the same base class.
f1
-
8/8/2019 dotNet - 2006 - 01
27/52
23
-
8/8/2019 dotNet - 2006 - 01
28/5228January 2006 dotnetdevelopersjournal.co
Performance
class to either Part or PartAssembly
(with new data members) would
require adding new columns to the
table, as well as new logic to identify the
additional class type.
Simplicity Calls
Wouldnt it be nice if all this discus-
sion of mapping strategies were unnec-
essary? As weve stated already, this sort
of class structure is easily modeled in
an OO language. It follows that the ideal
situation would be if that easy modeling
were simply extended to the database.
Put another way, our object structures
schema is built into the very architec-ture of our class definitions. Why should
we have to create yet another schema
for the back-end database, and then
build a mapping layer to translate data
from one schema to another? Wouldnt
it be nice if we could simply design our
classes, write our application, and store
objects right into the database as-is?
With an OO database, we can.
For the remainder of this article well
demonstrate how to do this by using an
open source database, db4o. Microsoft
.NET and Mono versions of db4o are
freely available from www.db4objects.
com.
Assuming that we have defined the
Part and PartAssembly classes as above,
and that the path to our database file is
in string variable filename, we can store
Part objects into a db4o database with
the code in Listing 2.
This is more like it. Rather than
clutter our application with SQL code
flanked by assignment statements
that pass object contents into bind
variables, we have a single call to a
set() method. Most important: notice
that we did not have to describe thestructure of a Part object to the db4o
database engine; it deduced that infor-
mation itself, via reflection.
Also notice that db4o invisibly
began a transaction for us. The db4o
engine supports the ACID database
concepts (atomicity, consistency, isola-
tion, and durability). We need merely
close the transaction with a call to
commit(). Had something gone awry
during the transaction, we could have
called abort(), and all operations that
had occurred since the last commit() o
open() would be rolled back.
Retrieving an object from this OO
database is just as easy as storing it. We
dont have to assemble an objects piec
es from multiple tables; instead, we capull it from the database with a single
call. All we need is a query mechanism
to identify the specific object we want.
db4o provides this mechanism via
its QBE (query by example) API. QBE,
as implemented by db4o, is an easy-
to-understand query technique that
uses a template object to define the
query. We fill the template objects field
with those values we want the query to
match. Fields that should not partici-
pate in the query are set to null or zero
(depending on the datatype).
Therefore, if we wanted to fetchthe Part object we had just stored into
the database, we could use the code
in Listing 3. The query in Listing 3
matches all Part objects whose name
field is Desktop Board D945GNT (we
presume there is only one). Matching
objects are placed in the ObjectSet
result. The ObjectSet class provides ha
Next() and next() methods, which allow
navigation-through-iteration on the
sets contents.
The query fetched a Part object
from the database. As defined, the
Part object is relatively simple that
is, it contains only strings as member
variables. The PartAssembly class,
however, contains a collection, and th
collection contains objects. One would
expect that fetching a PartAssembly
object collection and all would be
more difficult.
Actually, it is only slightly more
difficult. Although db4o lets us pull
an entire object tree into memory, we
might not want to. For example, we ma
want to fetch one or more PartAssemb
objects from the database, without
fetching the contained collection.
We can control how deeply db4oreaches into an object tree (when it
retrieves a complex object from the
database) by adjusting db4os activa-
tion depth. By default, the activation
depth is set to 5, which means that
retrieving a PartAssembly object would
also retrieve the collection. (So, fetch-
ing a wholePartAssembly would use
code that is virtually identical to the
code in Listing 3.) To retrieve only the
PartAssembly without the compo-
nents collection we can set the globa
category name manufacturer manufacturerPartNumbermemory
cpu
hard drive
PC-2 5400 DDR
Pentium 4
DiamondMax
Generic
Intel
Maxtor
25400 DDR
BX8O547PG32OOF
6Y25OMO6Y25OMO
category name manufacturer manufacturerPartNumber
Desktop Sys. Desk Mod 01 My Computers DTM0D01
PartAssembly Table
Components Table
Part Table
parent partDTMODO1
DTMODO1
PC-2 5400 DDR
Pentium 4
DTMODO1 DiamondMax
(a)
(b)
categoryc lass name manufacturer manufacturerPartNumbermemory
cpu
hard drive
Desktop Sys.
P
P
P
A
PC-2 5400 DDR
Pentium 4
DiamondMax
Desk Mod 01
Generic
Intel
Maxtor
My Computers
25400 DDR
BX8O547PG32OOF
6Y25OMO6Y25OMO
DTMOD)1
PartAndAssembly Table
Components Table
parent part
DTMODO1
DTMODO1
PC-2 5400 DDR
Pentium 4
DTMODO1 DiamondMax
Figure 2: Two techniques for mapping objects to relational databases. (a) Each class receives its own table.
The components collection (in the PartAssembly class) is stored in a separate table, with a foreign key reference
back to the parent item in the PartAssembly table. (b) Both Part and PartAssembly classes are stored in a
single table. A column is added to identify the class to which a particular row of data belongs.
f2
-
8/8/2019 dotNet - 2006 - 01
29/5229dotnetdevelopersjournal.com January 2006
activation depth to 0, prior to opening
the database as follows:
Db4o.configure().activationDepth(0);
Any database opened after theabove call would have its activation
depth set to 0.
Finally, deleting objects is as
straightforward as fetching them. If
we wanted to delete the Part object
retrieved in the Listing 3, it requires a
single line (placed where the ellipses are
in the listing):
Database.delete(mb);
followed at some point, of course, with
a commit().
Changes on the Fly
Suppose that a change in the
applications requirements demands a
change in an objects structure per-
haps something as simple as a new
field. For example, suppose that you
decided the Part class needed an alter-
nateSupplier field.
With an RDBMS back end, you
would have to modify one or more
tables, plus make additions to the
translation code, update the schema
mapping file, and so on. However, with
db4o, the alteration requires absolutely
nothing beyond the change to the Part
class definition (plus any added or
modified methods you would have to
write in any case):
public class Part {
private string category;
private string name;
private string manufacturer;
private string manufacturerPart-
Number;
private string alternateSupplier;
. . .
}
Everything else remains the same.
When db4o fetches a Part object from
the database, it will find no content foralternateSupplier, and set that field to
null. However, if we then assign a value
to that field and return the object to the
database, the effect will be to turn the
old Part object into a new one (see
Listing 4).
Thus, after the execution of the code
in Listing 4, any time we fetch from the
database the Part object associated with
Desktop Board D945GNT, it will have
an alternateSupplier field of Dougs
Board Outlet.
OO All the Way
An object-oriented database makes
a great deal of sense for a database
application whose content is easily
modeled in OO fashion. The mapping
code required to move data betweenobjects in the application and tables on
the RDBMS is eliminated. Furthermore,
such an application is simply easier to
work with, because there is no concep-
tual boundary that must be crossed
between the object model and the rela-
tional model.
The open-source database engine
db4o made our illustration of these prin-
ciples all the easier thanks to db4os API,
which is both easy to grasp and func-
tionally powerful. In one sense, db4o
hits a kind of sweet spot in that it is not
overly complex, nor under-powered.
A complete .NET application that lets
you create and manipulate a database
identical to what weve described in this
article is available from www.everylit-
tlething.net/PartsAssembly/ . The appli-
cation was written using Visual Studio
2005, and includes everything you need
to experiment with the Assembly data-
base structure. We encourage you to
explore the application, and discover the
benefits of OO all the way.
AUTHOR BIOs:
Rick Grehan is a QA engineer at
Compuwares NuMega Labs, whe
he has worked on Java and .NET
projects. He is also a contributing
tor for InfoWorld Magazine. His ar
have appeared in Embedded Sys
Programming, EDN, The Micropro
Report, BYTE, Computer Design,
other journals. He is also the coau
three books on computer program
Eric Falsken recently joined the db
team as technical evangelist aft
spending a few years working on
embedded medical devices as a d
user. He has been a staunch supp
of Microsoft .NET (much to the chof his open sourceloving co-work
and enjoys coming up with new id
elegantly usable software, and me
fellow students of software. You c
read his blog at www.everylittlethin
net/blog/.
Listing 1public class Part {
private string category;private string name;private string manufacturer;private string manufacturerPartNumber;. . .
}
public class PartAssembly : Part {private System.Collections.ArrayList components;. . .
}
Listing 2
// Open the ObjectContainerObjectContainer Database = Db4o.OpenFile(fileName);
// Create a new Part objectPart mb = new Part ( Motherboard,
Desktop Board D945Gnt,Intel,BOXD945GNT);
// Put it in the databaseDatabase.set(mb);
// Commit the transaction and// close the databaseDatabase.commit();Database.close();
Listing 3
// Create a Part template object
Part PartTemplate = new Part (null,Desktop Board D945GNT,null, null);
// Execute the queryObjectSet result = Database.get(PartTemp);
// Retrieve the matching objectif(Result.hasNext()) {
Part mb = (Part) result.next();// Do something with the Part. . .
}
Listing 4
// Create a Part template objectPart PartTemplate = new Part (
null,Desktop Board D945GNT,null, null, null);
// Execute the queryObjectSet result = Database.get(PartTemp);
// Retrieve the matching objectif(Result.hasNext()) {
Part mb = (Part) result.next();// Update the alternateSuppliermb.AlternateSupplier = Dougs Board Outlet;
// Return the object to the databaseDatabase.set(mb);
}
-
8/8/2019 dotNet - 2006 - 01
30/5230January 2006 dotnetdevelopersjournal.co
ne underutilized tech-
nique for maximizing
code reuse and increas-
ing developer produc-
tivity is the creation and utilization
of ASP.NET Server controls. Even
when the problem domain is well
known and understood, each
new project has many developers
starting at square one, dragging
and dropping the common Visual
Studio.NET controls onto a blank
form and having to manually
repeat the same processes that
other developers in the company
have had to perform in the past.
Server controls are an in-depth
topic and it would take an entire
book to do the subject justice.
In this article I will explain the
basics of how to create a type of
server control called a Composite
control, and to highlight some of
the differences between ASP.NET
1.x and ASP.NET 2.0 server con-
trols. (Source code is available by
viewing this article online in the
.NETDJarchives, http://dotnet.
sys-con.com/read/issue/archives/ ,[Vol: 4, iss: 1].)
The Case for Server Controls
Most businesses have certain
sets or types of information that
are ubiquitous to most of the
applications being developed.
Addresses, phone numbers, and
customer names are just a few
examples of common input col-
lections that are often duplicated
each time a new application is
being developed. Much of this can
of course be copied and pasted
from one application to another,
but when changes occur, these
changes must then be made in
multiple applications. An example
of this type of change would be
to an address for a company that
has recently gone international
and now must start capturing the
country where their customers
are located. By utilizing a server
control, the display and client-side
logic to handle this new data can
be coded once, with developers
now focusing on updating the busi-
ness logic.
The server control in our
example creates a simple user
interface (UI) for entering phone
numbers. It is composed of a
Labelcontrol, a TextBoxcontrol,
and two validator controls: one is
a RequiredFieldValidatorand the
other is a RegularExpressionValida
tor. One of the advantages of using
composite controls is that you
can utilize the ASP.NET controls
built-in behavior to minimize theamount of code you have to write.
For example, you will be able to
utilize the validator controls to per-
form their native functions without
having to write any control-specific
code.
Defining a Composite Control
One of the first things you
will probably notice if you are
familiar with developing server
controls under the ASP.NET 1.x
model is that our control inherits
from System.Web.UI.WebControls
CompositeControl(see Listing 1).
In previous versions of the .NET
Framework, you inherited from
Control and had to implement
the INamingContainerinterface.
These steps, along with other
functionality, are now taken care
of by the CompositeControlbase
class. The CompositeControlclass
also has an associated control
designer that ensures that child
controls are displayed on the
design surface.
You will also notice several attr
butes attached to the class defini-
tion. These help define various
characteristics of our control:
AspNetHostingPermission: This
is required to ensure that code
that links to the control has the
appropriate security permission
DefaultProperty: Specifies the
property to highlight in the
property browser when the pag
developer selects the control on
the design surface
ToolboxData: Used to specifythe format string for the design
environment created when the
control is added to a page
Define Composite Control
Properties
The next step in our compos-
ite control is to define the public
properties that will be accessible
via the property browser in Visua
Studio.NET. Most of the proper-
ties are a direct pass through to
o
BY WES WEEKS
Creating Composite Server Controlsin ASP.NET 2.0
Make new components from old
ASP.NET
-
8/8/2019 dotNet - 2006 - 01
31/5231dotnetdevelopersjournal.com January 2006
properties inherent of the controls
that make up our composite control
example. The code snippet in Listing
2 demonstrates this pass-through
technique.
One of the nice features of ASP.
NET 2.0 is the ability to assign a
group name to a set of validators to
ensure that validation occurs only for
controls in the specified group. This
enables you to have multiple sepa-rately-validated forms on a single
page. In our property example above,
the validation group is assigned to
both of our validation controls dur-
ing the set operation. It doesnt mat-
ter which validator controls property
we returned for the ValidationGroup
get operation and our arbitrary
choice was the value from the
phoneRequired control.
There are also several attributes
on the property worth mentioning:
Bindable: Indicates that the prop-
erty supports data binding
Category: Determines which cat-
egory this property will be associ-
ated with on the PropertyGrid
Description: Tells the developer
who is using the control what the
property does
Adding the Controls to the
Controls Collection
The next step in the process
is to add the controls that make
up our composite control to the
Controls collection of the base
CompositeControlsclass. This is a
fairly straightforward process andsimply involves initializing our
controls, setting any default prop-
erties, and then utilizing the Add
method to add them to the con-
trols collection by overriding the
CreateChildControls() method (see
Listing 3).
Define Style Properties
Defining and using styles under
ASP.NET 1.x took a considerable
amount of work. Simply exposing
the Style property of the controls
within the composite control
didnt work as expected, and though
you would see the Style settings
displayed in the property grid, set-
ting them did not translate into
run-time functionality. One of the
reasons for this is that the ASPX
page didnt have a location to store
the values of the style settings.
This has been remedied in 2.0 andmultiple style properties can be
exposed and recorded in the ASPX
page to allow styles to easily be set
at design time. Our property for
each style sheet resembles any of
the other properties we have cre-
ated. The way ASP.NET handles the
Style properties can be viewed by
looking at the HTML view in Visual
Studio.NET.
In this example we have set a
specific style for the Label by set-
ting the LabelStyleproperty in the
property grid. This was translated
into the LableStyleelement as a
sub element of the phone control
itself.
Creating Custom Functionality
Although creating a composite
control in and of itself provides aconsiderable benefit in terms of
code reuse and faster development,
it is always nice to provide some
additional functionality to enhance
the controls usefulness. For our
example we are going to provide the
ability for our control to automati-
cally put the phone number that
is entered into a standard format.
In order to accomplish this, we are
going to render some JavaScript on
the client that will be called when
our control loses focus to provide
the formatting (see Listing 4).
The call to this method to render
the JavaScript occurs during the
OnPreRenderevent. The neces-
sary control attribute to call the
JavaScript function when the text-
box loses focus was rendered in our
CreateChildControls() method.
AUTHOR BIO:
Wes Weeks is president and CEO
of AgileWise, a software develop-
ment and consulting firm based
in Topeka, KS. Wes has extensiv
experience in object-oriented
technologies, enterprise applicati
architecture, and service-oriented
architecture design and develop-
ment. He is currently consulting f
Security Benefit, an organization
named one ofCIO Magazines
Agile 100 in 2004 that has suc-
cessfully employed numerous Ag
methods and processes.
There were several changes to the ASP.NET server control model that improve upon
the server control object model and to make control development easier. The list below
highlights some of the most notable changes:
ControlState: This is an alternative way for developers to persist control properties
in the page without using ViewState. The advantage is that while ViewState can be
turned off at the page level by the developer, ControlState cant, so the control devel-
oper can be assured that data that has to be persisted for proper control function cant
be turned off
ValidationGroup: Allows a group of controls to be validated together so that the devel-
oper can enforce validation on a subset of controls on a page
CompositeControl: A new class that can be inherited from by control developers that
eases the development and creation of composite server controls
Styles: Working with CSS Styles has been made easier with the ability to expose Style
properties into the property grid and have those changes created and stored in the
ASPX page at design time
Changes Between Developing Server ControlsUnder ASP.NET 1.x and 2.0
By utilizing a server control, the display andclient-side logic to handle this new data can becoded once, with developers now focusing on
updating the business logic
-
8/8/2019 dotNet - 2006 - 01
32/5232January 2006 dotnetdevelopersjournal.co
ASP.NET
One thing to note for those
who have developed server con-
trols under the 1.x paradigm is
the ClientScriptproperty of the
Page object. The ClientScript
property is an object of type
ClientScriptManagerand should
be utilized instead of the Page.
RegisterClientScriptBlock() method
that has been deprecated. It has afew new arguments, including ask-
ing for a type in addition to the key
field to assist in matching up the
client script to the control, as well
as the ability to have the method
automatically output the script tags
by setting the addScriptTagsargu-
ment to true, which is shown in this
example.
Override the Render Method
The last step in the control
creation is to override the render
method to provide the formatting
for our control on the page. In this
example we render the multiple
controls that make up our compos-
ite control within a table to be sure
the way the control gets rendered is
consistent in any page that may
use the control. This is also the
location of where we render any
Style attributes that are set at
design time by the page developer
(see Listing 5).
Building and Using the Control
The last step in the process is
to add our created control to thetoolbox so that we can add it to
our page by using drag and drop.
The easiest way to do this is to
open the toolbox panel, right-
click on add/remove items, and
then browse to the bin directory
containing the assembly for the
server control. This will add our
control to the toolbox and from
there it can be added to a Web
form like any of the built-in con-
trols. After adding a control to the
toolbox we can now create a Web
project. With the Web project
newly created, drag and drop the
phone control from the toolbox to
a Web form. Lets also add a valida-
tion summary control and a submit
button.
Start the Web project and enter
in the area code and phone numbe
without any symbols or format-
ting. Notice how the number neatl
formats itself when you move off o
it provided it has either 7 or 10 dig-
its. If it doesnt, formatting doesnt
occur and the form wont submit
due to our regular expression vali-
dator. If you have set the Requiredproperty to true, the form will pre-
vent you from submitting a blank
number as well.
Summary
This fairly simple example dem
onstrates how easy it is to begin
creating custom server controls tha
can be used to provide common
functionality for your applications
It demonstrates how to create a
composite control, apply styles, an
add custom functionality. Spendin
the little bit of extra time to develo
a custom control can result in pro-
ductivity gains for developers and
ease making global changes to the
front end by having a single contro
to maintain.
Listing 1
[AspNetHostingPermission(SecurityAction.
LinkDemand,
Level = AspNetHostingPermissionLevel.Minimal),
DefaultProperty(Text),
ToolboxData(
)]
publicclass PhoneControl : CompositeControl
{
private Label phoneLabel;
private TextBox p