Whereas the current version of ADO.NET provides the ability to invoke commands against database connections, the Entity Framework uses code generation to turn tables and columns into objects and properties. While this initially reminded me of the code generation provided by strongly typed DataSets, the code generated by the Entity Framework uses partial classes that are easily extensible. Auto generated entities and associations are modifiable to enable custom views of the data for each particular application. And designers allow you to visually define and alter resulting generated code.
The framework abstracts the database objects such that a logical representation of a typical 1-many relationship looks like an object with a collection of related child objects. Table joins are hidden from the database developer by mapping the relations, called associations in EF, within an Entity Data Model.
The Entity Framework provides a number of features to make the sessions with the database work very naturally without writing a lot of configuration and connection code. This will hopefully dissuade developers from practices like hard-coding connection strings into the application.
Overall, this looks like an interesting data access technology and I am looking forward to how it looks when it RTMs.
A LINQ statement comes in many flavors, depending on each LINQ-enabled data source. Here is a VB.NET example of a simple statement for SQL:
One very interesting feature of LINQ to XML is that it enables dynamic creation of Xml elements using Xml-like elements directly in our source code:
Many LINQ features that were missing last year are now available; including the ability to make insert, update and delete operations.
Finally, for those who would want to try LINQ, Eric pointed out that Visual Studio Orcas ships an updated version (April 2007) of the CTP for Visual Studio 2005 (May 2006).
Generics are, in my opinion, one
of the best and most under-utilized features added to the .Net framework in
version 2.0. Rob provided a basic overview on this topic to help overcome that
issue. He started off by discussing how things were done before generics were
available and the issues with casting and especially boxing value types.
Collections are one of the most
obvious uses of generics, and Rob used that as the first sample to get
everyone's feet wet. ArrayList was a common collection type used prior to the
introduction of generics, which he used to demonstrate that there is no way to
enforce strong typing on the members of the ArrayList. This could result in data
inconsistency and worse, runtime exceptions that could have otherwise been
caught during compile.
The pre-generic way to avoid
these potential for runtime errors was to construct a custom collection class
where the properties and methods that allowed adding and retrieving members
enforced proper typing. This was cumbersome and not reusable resulting in a
great deal of coding to ensure type safety.
By using generics, we can simply
define a collection of a specific type. This is a much simpler implementation,
prevents runtime errors, and also prevents the boxing/unboxing that occurs with
value types.
Within
the System.Collections.Generic namespace, the List<T> object is
a generic-based replacement for the ArrayList. By convention, the type
placeholder when defining a generic collection uses an uppercase "T" but any other letter or
variable can be used in its place. For example a list of integers would be
represented as
Generics allow classes to be
parameterized by the types they store and manipulate. While collections are a
popular use of generics, they are extremely useful in defining general purpose
classes that do not necessarily contain a list of items.
Not only can classes be defined using generics, but methods within a class can be generic, providing flexibility in the types that can be passed to the method as parameters. This allows methods to be used against any types making them much more flexible.
But sometimes you don't want to make types and methods that are generic for any type. The framework provides constraints that you can place on the generics definition. You can constrain your generics in a few ways. You can do so by constraining the generics to be of a specific type or a type derived from that specified. Another method of constraining is by defining that the type passed in is either a value or a reference type. And finally, you can enforce that only types that have a default constructor provided are passed into the generics declaration.
The .Net framework provides a number of generic types and interfaces that can be used for your own generics to inherit or implement or to be used in constraining your generic types and methods.
Then Rob went into some of the details of using static members within a generic type. Each unique set of type parameters passed to a generic type declaration will share any static properties and methods. He demonstrated this with showing the IL code generated from two different instances of a class with a shared property count that was incremented in the type constructor.
Most of the new C# language features were made necessary by LINQ. What I really appreciated in this session was that Claudio showed us with many demos how each of these features can be used on their own.
The first feature was Automatically Implemented Properties; tired of writing setters and getters for each of your fields? Now you can simply specify the property name and the compiler does the remaining work for you (this doesn't work for read only properties):
Claudio also demonstrated Type Inference with the new "var" keyword and the Extension Methods. These last ones are used to extend existing classes without altering their declaration. In one of the examples, we saw how a null reference could be used in this fashion without raising an exception:
Then Claudio presented Lambda Expressions, which can be seen as a simplification of Anonymous Methods, and how they are represented in Expression Trees. Here is an example of an Anonymous Method and its equivalent Lambda Expression:
The last two features were Object Initializers, which are used to initialize any public property of an object at creation time, and Anonymous Types which are implicitly-named classes generated by the compiler. Finally, Claudio explained how all these features are relevant in LINQ and he concluded with this interesting piece of code:
The Performance Dashboard is intended to augment Profiler and Performance Monitor to manage resource utilization. It helps to identify CPU utilization issues, waits, blocks and missing indexes. The dashboard does have some limitations, but given that this is a 1.0 release, that is not unexpected. It currently requires manual installation. The number of reports is somewhat small for this release. But this is essentially a preview of what is to come when Microsoft releases Katmai, the next version of SQL Server, sometime in 2008.
SQL Server 2005 SP2 is required for the performance dashboard to be installed. It is essentially a series of pre-defined reports using the Custom Reports feature introduced in SP2. The download is 1.4 MB. Running the install creates a folder with the report definitions, a SQL script which must be run for each database instance in which you want the dashboard to run, and a help file which is a worthwhile read. Brad also recommends spending time with the SQL script file as well because this provides some insight into the use of some obscure and even undocumented DMV usage.
After going through the PPT deck, Brad switched into demo mode. To demonstrate some of the performance reports, he intentionally placed his database server under a heavy load.
Once launched, the dashboard displays a main report that acts as an entry point to the other, more detailed reports. The main report includes a chart showing the last 15 minutes worth of CPU utilization. By clicking within the graph, another report providing more detail is displayed. Included in this detailed report are the top 15 busiest queries. By that it means most often run queries. Each query provides lots of detail such as total number of milliseconds all executions of the query ran as well as max execution time, average execution time, number of logical reads, etc. You can also get the execution plan from the report. It is currently only the text version, but you can alter the report definition (rdl) file to use SHOWPLAN XML instead.
The Wait States section of the main report allows you to drill into the details of all wait states that have occurred since the database instance was last started. The Sleep wait state is common and not really an issue. Typically this will be the greatest amount of waits listed on the report. You can generally ignore this and move onto the other wait states with a high occurrence. Watch the ones that actually affect system resources such as Disk I/O, Network I/O, and memory. This can help you identify the bottlenecks in your system.
The Historical I/O report is also helpful in determining which databases are incurring the most I/O. It even shows both I/.O utilization of the transaction log. Included in this report is a list of missing indexes that the optimizer has logged as having been beneficial if they had been present. It will identify covering indexes using the new INCLUDE clause of index creation.
Brad recommends the Duration and the Logical Reads reports as being some of the most useful in determining performance issues. The Active Trace report is also informative. By default, SQL Server 2005 starts at least one trace which could be optionally disabled to improve performance on busy production servers.
I found this to be an interesting topic covering a much needed tool in performance tuning our databases. I only wish it were available during my last project.
Wednesday, May 16
Configuration Management in .NET (Fundamentals)
Don Kiely
by Martin Lapierre
I decided to write about this session because it contained basic material
that every developer should know about configuration even if it's been around
for awhile. As an introduction, Don made an overview of the .NET configuration
system and explained how an app.config or a web application web.config file
overwrites the default configuration information of the machine.config and root
web.config files. He later demonstrated this by displaying the content of a
merged file generated by the WebConfigurationManager using code similar to
this:
string sFile = @"C:\Samples\full.web.config.xml";
Configuration config =
WebConfigurationManager.OpenWebConfiguration(
"/ConfigASPNET" ); config.SaveAs(
sFile, ConfigurationSaveMode.Full, true );
The System.Configuration and System.WebConfiguration namespaces provide the classes that we can use to read, manipulate and modify configuration data. A web or a windows application uses a configuration manager to access either the default or a specific configuration file. The Xml content of the file is then translated into strongly-typed configuration objects such as sections, section groups, section properties and collections. Here's an example of how to read and access a property of the identity section in a web.config file once it has been loaded as an object:
Configuration config =
WebConfigurationManager.OpenWebConfiguration( "/ConfigASPNET" );
IdentitySection identitySection =
( IdentitySection )( config.GetSection( "system.web/identity" )
txtResults.Text =
"Impersonate is set to " + identitySection.Impersonate.ToString();
The most useful thing in the .NET 2.0 configuration
features is that we can define our own configuration sections, collections and
properties by creating custom section handlers. When creating section handlers,
we can define properties declaratively or programmatically. In the fist case, we
use the ConfigurationPropertyAttribute attribute to declare a property:
[ ConfigurationProperty( "Information", IsRequired=true ) ]
public string Information
{
get { return this[ "Information" ].ToString(); }
set { this[ "Information" ] = value; }
}
And when doing it programmatically, we can take advantage of validation attributes, a feature which is not available declaratively:
[ RegexStringValidator( @"^\w+@[a-zA-Z_]+?\.[a-zA-Z]{2,3}$" ) ]
public string Information
{
get { return this[ "Information" ].ToString(); }
set { this[ "Information" ] = value; }
}
Don's demos also efficiently showed how to create
complete sections, section elements and collections by deriving classes from
ConfigurationSection, ConfigurationElement and ConfigurationElementCollection.
His demos were simple and easy to follow, and were provided both in VB.NET and
C#.
Chasing the Silver Bullet - SOA Myths and Opportunities
Rob Daigneau
by Tom Cooley
Rob is the director of Application Architecture for
monster.com and hosts the website designpatternsfornet.com
Looking back at the past, there have been a number of attempts to solve the
problems of application complexity and interoperability. Each step has been
evolutionary in nature. Windows DNA and COM promised many of the same solutions
that all the hype of SOA claims. These include service reuse, reduced
development cycles, and cost efficiencies.
SOA makes the same claims that were promised more than 10 years ago. Vendor
neutrality, software versioning, better data integrity, performance, and
scalability are more claims made by the SOA pundits.
Part of the problem with SOA is that the term itself gets redefined by
vendors to match their product offerings. According to Rob, SOA is really just
"a design style which promotes the delivery of software operations that usually
complete some unit of work." He outlined four tenets of service orientation
espoused by Microsoft: Boundaries are explicit Services are autonomous Services
share contracts Compatibility is policy-based
Yet Microsoft breaks some of these tenets themselves. For example, DataSets
are commonly returned from web service calls, yet that is platform specific and
therefore incompatible with other service consumers implemented on another
platform such as Java.
A key concept to SOA is the contract. A service exposes the contract to
consumers. Consumers must know the contract, policies associated with it, as
well as the proxy to connect back to the service endpoint.
Most people believe SOA and web services are synonymous when in fact web
services are merely a common implementation of service orientation. Another
common misconception is that SOA guarantees loose coupling. However, it goes
back to the contract. If the service must make a change, either in the service
contract or in its policies, you require a change to the consumers of that
service. That is a form of coupling. Most of the promises of SOA are not really
attained simply by following SOA. Many of the claimed benefits of reuse and ease
are not really gained by service orientation per se. Of these promises, platform
and vendor independence are the easiest to attain through service orientation.
But many of the proclaimed benefits are not solely within the domain of SOA. In
fact the performance gains claimed are really hard to attain. In most cases,
public services use http as its protocol which is inherently slow an unreliable.
But this talk was not just an attack on SOA. Instead, it was intended to tear
away the hype and debunk the myths, while looking at the real opportunities that
a service oriented architecture can provide.
Some of the more realistic goals for SOA include smaller, more discrete
assemblies which equate to smaller memory footprint and faster build times. SOA
can certainly aid in providing highly scalable solutions, though it is not the
only factor involved. Separation is also an attainable goal using service
orientation. And although performance is generally not considered a strong
characteristic in many cases, WCF addresses many performance issues by providing
faster, more efficient transports.
For me, the take-away was to evaluate SOA on its technical merits and to try
to ignore the hype. I think this was Rob’s primary objective for the session.
Asynchronous Programming for ASP.NET 2.0 Developers
Julie Lerman
by Martin Lapierre
In general, the goals of asynchronous programming are to enable parallel
processing of an application's operations, to make a user interface more
responsive to user input and to make a system take advantage of multiple
processors. Although this session covered how to develop asynchronous operations
in ASP.NET 2.0, some of the techniques presented by Julie could also be used in
non-web applications to achieve these same goals.
Traditionally, ASP.NET will answer a request by taking a thread from the web
application thread pool and by executing code synchronously on that thread until
the response is sent to the client. If an external or remote process (such as a
database server) is called during the code execution, the thread from the thread
pool will be locked and unavailable to answer other requests. By implementing
asynchronous operations, we can make ASP.NET free up the thread without waiting
for a lengthy operation to complete; when that operation ends, ASP.NET will take
another thread from the thread pool and will continue answering the initial
request.
Julie first demonstrated two ASP.NET techniques to integrate asynchronous
calls in a web page. The first one was to set the "async" property of a page to
"true" and to use the Page.AddOnPreRenderCompleteAsync method to register
callbacks for the beginning and the ending of the asynchronous operation.
Implementing this technique may not be the best practice to follow, because it
is limited to one asynchronous call. If you have multiple asynchronous calls to
make in parallel, it's better to use the other technique: asynchronous tasks.
You first create your callbacks and an instance of a PageAsyncTask, which will
contain the handlers to your callbacks and some extra information for the
behavior of the asynchronous operation. Then you register the task to the page
using Page.RegisterAsyncTask – doing it multiple times if you have many
operations to execute concurrently.
' Registering an asynchronous task.
Dim task As New PageAsyncTask( New BeginEventHandler(AddressOf BeginLongProcess), _
New EndEventHandler(AddressOf EndLongProcess), _
New EndEventHandler(AddressOf TimedOut), Nothing, True)
Me.RegisterAsyncTask(task)
Julie also covered asynchronous Web Services and
asynchronous data access. A .NET 2.0-generated Web Service proxy always comes
with synchronous and asynchronous methods. The great thing is that the mechanism
is implemented with events and not with callbacks implementation. So, when
calling a Web Service asynchronously, all you have to do is to register your
event handler to the method-completed event and call the asynchronous
method:
Private ws3 As localhost.SlowService
Protected Sub Button1_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Button1.Click
ws3 = New localhost.SlowService
AddHandler ws3.ThreeSecondHelloCompleted, AddressOf ThreeSecondCompleted
ws3.ThreeSecondHelloAsync()
End Sub
Private Sub ThreeSecondCompleted(ByVal sender As Object, _
ByVal e As localhost.ThreeSecondHelloCompletedEventArgs)
lblmsg.Text = e.Result
End Sub
Finally, asynchronous data access is made available thru
SqlCommand and the BeginExecute/EndExecute prefixed methods, which work with
callbacks similarly to ASP.NET.
Applied Patterns of Enterprise Application Architecture
Jean-Paul Boodhoo
by Tom Cooley
This is obviously a hot topic because the room was
completely packed. And to encourage people to fill out their evaluations,
Jean-Paul, offered free licenses to ReSharper to the first five people who
submit their comments.
The prerequisites for this topic are an understanding of the dependency
inversion principle and dependency injection. The basic principle is that
"high-level components should not depend on low-level components; they should
both depend on interfaces."
Jean-Paul provided some recommended resources on design
patterns including HeadFirst Design Patterns
. Despite the fact that all of the samples are written
in java, it is a very well written book and is an easy read. The language
implementation is irrelevant to the patterns being described.
Jean-Paul demonstrated a poorly architected web form that has several
responsibilities that it should not, such as opening a db connection, getting
raw db data, and mapping it to a list of employee objects. In refactoring the
sample application to focus each layer on its own responsibilities, Jean-Paul
introduced the Passive View design pattern.
The Passive View deign pattern attempts to relegate UI to the responsibility
of accepting user input and displaying output. PassiveView is a form of
Model-View-Presenter. By refactoring the additional behaviors out, we achieve
greater separation and more resilient components. The Presenter in this pattern
will use indirection to abstract the final UI technology from the service we’re
developing. Passive View uses an Observer model. The view implements an
interface that among other things, defines an event. The Presenter subscribes to
these events.
The initial refactoring only took us so far though. It essentially removed
the additional responsibilities out of the web page and into the Presenter in
the Passive View. Now the Presenter has too many responsibilities. To correct
this, Jean-Paul used the Service Layer pattern, an implementation of the Gang of
Four Façade design pattern. This pattern also uses interfaces to provide a layer
of abstraction between the service layer and its consumer.
Yet, once again our refactoring was not complete, the higher-level components
of View and Presenter had been successfully decoupled from the lower-level
components, but the new service layer still had an added responsibility of
mapping data returned from the database to the domain objects. This was to be
solved by the Data Mapper Pattern.
Unfortunately, several questions from one member of the
audience detracted the session to the point where Jean-Paul was unable to finish
his presentation in the allotted time. Luckily, the May/June edition of CoDe
Magazine contains an article Jean-Paul wrote which appears to cover everything
in the presentation. And given that this magazine was included with the DevTeach
packets handed out at registration, we all have access to what I thought
was a valuable talk.
Thursday, May 17
Building Silverlight Applications using .NET (Part 1 &
2)
Yair Alan Griver
by Martin Lapierre
This was yet another great two-part session. Yesterday, Yair
Alan Griver did quite an introduction of the flashy Microsoft Silverlight and
continued today by using .NET 3.0 and LINQ features right into that new technology.
So new in fact that Alan just had a few days before DevTeach to build up his
presentation - and he did quite a good job.
But wait a minute - what is Silverlight?
Silverlight is a new Rich Internet Application (RIA)
technology which comes in the form of a web browser plug-in. It offers a subset
of the Windows Presentation Foundation (WPF) that can run inside a browser. We
could think that Microsoft just decided to bring back the old ActiveX
technology, but we’d be wrong. Silverlight is much, much more than that: the
plug-in can be installed on either Windows or Mac OS X and supports Firefox,
Safari and Internet Explorer.
XAML is at the root of the Silverlight technology (XAML is
the XML-based document format that is also used by WPF and tools like Microsoft
Expression Design and Microsoft Expression Blend). This means that a web
designer can work in graphical tools to create his user interface and save that
in a XAML document onto which web developers can hook server code and events.
Developers can even modify the XAML document and the changes will be reflected
back in the web designer tools.
So, are Silverlight and XAML meant to replace ASP.NET and
HTML? The answer is no, or not yet. In the current beta version, Silverlight
doesn’t provide a rich set of controls; the 1.1 alpha version may not even ship
a textbox! In fact, the user interface is specified with shapes (Rectangle,
Ellipse, Line, etc), which can be made to represent complex objects.
A Silverlight application can be interacted with and
embedded in an ASP.NET and an ASP.NET AJAX application using JavaScript; the Silverlight
plug-in exposes its internal Document Object Model (DOM) to the browser, which
makes this possible. Here is an example where a Silverlight "control"
is used in an HTML page which also contains a textbox and some JavaScript
invoking one of the Silverlight control method (code edited out for clarity):
<cc1:Xaml ID="Xaml1" runat="server" Height="798px"
Width="1002px" Windowless="true" XamlUrl="~/Page.xaml"/>
<input id="Text1" type="text" />
<script type="text/javascript">
function Search()
{
var input = document.getElementById("Text1");
var control = document.getElementById("Xaml1");
//Call the scriptable event
control.Content.BaseballData.Search(input.value);
}
</script>
Although Silverlight cannot be used to create 3D,
out-of-browser and off-line applications, it is a beta technology that is worth
following, as it promises wonders for the future of web development.
SQL Server 2005 Worst Practices
Roman Rehak and Peter Debetta
by Tom Cooley
You often read articles on 'best practices' for performing
various tasks, but it is rare to hear the other side of the coin. Roman and
Peter collaborated on a list of the traps and pitfalls to avoid when designing
and developing database systems. This was a fun session highlighting some of
the “Stupid Human Tricks” we that call ourselves database professionals may
have performed throughout our illustrious careers. I personally have never done
any of these worst practices. That’s my story and I’m sticking to it. The
session is broken out into three main topic areas, Administration, Database
Design, and Programming.
Peter asked for a show of hands on how many people perform backup
on their databases. More or less all hands (of dba's
responsible for such a task) went up. He followed on with how many verify their
backups. Some hands went down. He then asked how many have performed a test
restore. More hands went down. The point being is that disaster recovery cannot
be an afterthought. Failure to plan is a plan for failure. Backup your
databases, make sure the Verify option is turned on for those backups, and
perform a test restore as part of your disaster recovery plan.
From the security standpoint, mixed mode security should be
avoided if at all possible. Using 'password' as your
password, especially for the 'sa' account, is
obviously a worst practice. Likewise, using the sa login within the application is a bad idea. Even
granting a login dbo access on a database is also
generally granting more privilege than necessary.
When updating production databases, and even non-production
ones, you should never just use things such as the table design GUI to execute
these changes. It is fine to use the GUI to generate a script, but the script
should be verified to ensure the functionality will occur as you expect. Then
you should thoroughly test the scripts before executing in a production
environment.
On to database design. Databases contain tables. That's
plural - with an s. When creating a database, don't try to stuff all of your
content into one table. That's what they built Excel for. If you've been bold
and wise enough to create more than one table in your database yet do
not enforce referential integrity via foreign key relationships, you are asking for data integrity issues.
SQL Server automatically makes primary keys clustered by default.
This can be convenient in many cases. But you should not just accept that
the PK is always the best choice for your clustered index. You only get one.
Choose wisely. When scripting database objects, it is important to be explicit.
When naming stored procedures, do not use
sp_ as the prefix. Doing so will cause SQL Server to look first in the
system database thereby incurring a performance hit.
When naming tables, choose whether or not to
pluralize table names or not. There is debate on which is proper. Is it
Customer or Customers. In fact, this is one point where
Roman and Peter disagree. Roman, who is on the pro-plural side stated, "When
I go to the store to buy cereal, I don't get a box of Rice Crispy." The point
is choose one and be consistent. Also, prefixing objects with things like "tbl"
has gone out of style. Like bell bottoms and platform
shoes, Hungarian notation is a mistake of the past that should not be repeated.
Don't stuff character fields consisting of numbers into
numeric data types. This includes phone numbers, zip codes and social security
numbers. Numeric data types are intended to perform mathematical operations.
When was the last time you needed to average phone numbers or sum zip codes?
These are character fields. They just happen to be limited to characters 0 – 9.
There is no longer any reason to use text, ntext and image data types when developing new applications
against SQL Server 2005. Varchar(max) and its Unicode counterpart are preferable.
On the programming side, the recommendation is to no longer
hand code standard CRUD procedures. There are many code generation options
available that build the scripts for you. Other practices that are now obsolete
are to replace @@ERROR with TRY/CATCH and replace @@IDENTITY with scope_identity.
SQL CLR is not the new T-SQL. T-SQL is still the preferred
language at least for set based operations. CLR programming can be powerful but
its usage should be closely scrutinized.
Thanks to Roman and Peter for pointing out my...I mean the
other attendee's shortcomings. I'm off to go test my backups.
XML Features in SQL Server 2005
Peter DeBetta
by Martin Lapierre
This year, the DevTeach conference also includes the SQLTeach
conference. My coverage couldn’t have been complete without a few words on a
SQL session. I have decided to talk about Peter DeBetta's presentation of the
integrated features of XML, because XML is now critical to so many applications
that it just makes sense to discuss it from a developer point of view.
SQL Server 2005 can handle XML as a native data type. I said "can",
because if you store XML documents in your database without any
need to validate or perform queries on them, it is more efficient to simply store
them as good-old binary fields. But otherwise, the XML data type is your new
best friend; it can support an XML document of up to 2GB and can be
associated with an XML schema to make sure that only valid XML documents are
inserted in your database. Where data manipulation is concerned, the XML data
type can be converted to/from character and binary types and supports advanced
querying capabilities thru XQuery and XPath 2.0. Note that an XML column can
only be indexed using an XML index.
When creating a table with an XML column, it is possible to
create a constraint between the table's primary key and the content of the XML
document. In the following code snippet, the constraint forces the ResumeID
column to must match the ResumeID attribute of the xml document:
CREATE TABLE ContactResume
(
ResumeID int NOT NULL PRIMARY KEY,
Resume xml(xscResume),
CONSTRAINT ckResID CHECK(ResumeID =
Resume.value('Resume[1]/@ResumeID','int'))
)
The XML data type also comes with a predefined set of
methods: exist(), value(), query(), modify() and nodes(). They can be used in
T-SQL statements to get, test or modify the XML content.
One very precious piece of information Peter gave about XQuery
was that we can actually use variable or column values in query expressions,
which may help to remove the need for dynamic SQL. The next example is taken
from the SQL Server 2005 Books Online, as the session scripts were not
available at the time of this writing:
SELECT P.ProductID, CatalogDescription.query('
declare namespace pd="http://schemas.microsoft.com/sqlserver/
2004/07/adventure-works/ProductModelDescription";
{
if (not(empty(/pd:ProductDescription))) then
attribute ProductModelName { /pd:ProductDescription[1]/@ProductModelName }
else () }
') as Result
FROM Production.ProductModel PM, Production.Product P
WHERE PM.ProductModelID = P.ProductModelID
AND CatalogDescription is not NULL
ORDER By PM.ProductModelID
Peter also covered many of the FOR XML enhancements, which
can be used to generate XML from the standard and XML data types. They provide
much more flexibility than in SQL Server 2000 and are worth investigating on
your own if you need to return customized XML output.
This concludes my DevTeach 2007 coverage. I'd like to thank Tom Cooley for his
contribution to this experience and for having the patience to edit, format and
upload the articles so that they could finally made their way to Universal
Thread.
ADO.NET Orcas Overview
Julia Lerman
by Tom Cooley
Julie's goal for this talk was to expand upon and dig deeper
into the topic of the Entity Framework overviewed by Pablo Castro in the
Keynote Address. Since much of this talk is about the Entity Framework, Julie
(with tongue in cheek) struck out Orcas from her slide title and placed Katmai
in its place because Microsoft just announced that this feature will be delayed
to the Katmai timeframe.
Speaking of delays, as Julie began her presentation and had
barely made it to the second slide, one of the hotel organizers came in and
announced that we needed to relocate to another room. Le Caf Conc, which I'd
heard at least one speaker refer to as the "Muppet Theatre", was apparently
being used for a dinner later and the staff needed to prepare the room. We all
packed up our stuff and shuffled across to the main hall, only to realize that
no projector or screen was available.
With a lot of content to cover and time already wasted on
the relocation, Julie hopped up on the stage and continued her talk without the
visual aids. Meanwhile hotel staff brought in the projector equipment and setup
around her. All of this provided quite a distraction but I have to give Julie
credit for handling it so gracefully. Now on to the content itself.
As stated above, this talk was an expansion of the overview
provided during the Keynote, but Julie also provided a brief overview of the
main points covered by Pablo as a foundation before drilling in deeper (see the
Keynote session for more details). Note that this is a very big topic and
essentially amounts to a paradigm shift in the way we will with data from an
applications perspective.
One goal of the Entity Framework is to provide to the
application developer an object model that more closely represents the problem
domain being addressed. It does this by translating highly normalized database
tables with complex relationships into entities with properties to represent
table columns and associations to related tables. The framework is based upon
the concept of Entity Data Modeling. The Entity Data Model (EDM) defines three
Xml files that describe each entity and relationship, the physical storage of
the tables and columns, with data types, foreign key constraints and
cardinality, and a list of mappings between each entity and its storage
representation.
A wizard interface is provided for connecting to the
database and generating the Entity Data Model. An entity connection string
provides much the same information as a standard connection string, but also
contains additional metadata used to aid in creating the Entity Model. After
the desired tables are selected the wizard creates the model as the three Xml
files listed. Because this is beta software, tooling is still limited. Julie spent
some time walking us through the Xml files generated to help provide an
understanding of the plumbing underneath the model.
There are many levels of abstraction within this framework.
It can be as easy as dragging an entity onto a form control and setting a few
properties. Or you can generate an object data source from the EDM. Note that
an Entity is much like a Data Transfer Object (DTO) in that it only had
properties that represent the values of the entity. The object data source is a
partial class that can be extend with additional properties and behaviors. This
level of abstraction makes programming against the database far easier to do.
The plumbing code is generated and can be run without modification if you like.
Julie also spent time talking about LINQ and its various
flavors, including LINQ for Objects, LINQ for Entities and LINQ for SQL. LINQ for
Entities will allow developers to interact with the Entity Framework, producing
strongly typed objects and collections from the Entity Sets.
The Entity Framework will also provide an API to program
against EDM objects using an EntityClient, much like the SqlClient available in
current versions of ADO.NET. This will allow you to begin using entities and
the EDM while still using code that returns IDataReader.
All the functionality in ADO.NET 2.0 is still there. This
should allow developers to ease into this new paradigm while preserving
existing code bases. At present, for myself and most of the attendees, there is
a lot of information to digest regarding the Entity Framework and all of its
new syntax and object types. Yet I suspect in another year or so, this will all
seem so normal and we’ll wonder how we ever worked with that database before.