this.customerBindingSource.DataSource = cust;
}
}
Vb
Private Sub btnLoad_Click(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles btnLoad.Click
Using aw As New AdventureLiteDataContext
Dim loadOptions As New System.Data.Linq.DataLoadOptions
linQ to sQl .
617
loadOptions.LoadWith(Of Customer)(Function(c As Customer) c.Orders)
loadOptions.LoadWith(Of Order)(Function(o As Order) o.OrderItems)
loadOptions.LoadWith(Of OrderItem)(Function(oi As OrderItem) _
oi.Product)
aw.LoadOptions = loadOptions
Dim custs = From c In aw.Customers
Me.CustomerBindingSource.DataSource = aw.Customers
End Using
End Sub
Essentially what this code tells the DataContext is that when it retrieves Customer objects it should
forcibly navigate to the Orders property. Similarly, the Order objects navigate to the OrderItems
property, and so on. One thing to be aware of is that this solution could perform really badly if
there are a large number of customers. In fact as the number of customers and orders increases, this
will perform progressively worse, so this is not a great solution; but it does illustrate how you can
use the LoadOptions property of the DataContext.
The other alternative is to not dispose of the DataContext. You need to remember what is happening
behind the scenes with DataBinding. When you select a customer in the data grid, this will cause the
OrderBindingSource to refresh. It tries to navigate to the Orders property on the customer. If you
have disposed of the DataContext, there is no way that the Orders property can be populated. So
the better solution to this problem is to change the code to the following:
c#
private AdventureLiteDataContext aw = new AdventureLiteDataContext();
private void btnLoadData_Click(object sender, EventArgs e){
var cust = aw.Customers;
this.customerBindingSource.DataSource = cust;
}
Code snippet CustomersForm.cs
Vb
Private aw As New AdventureLiteDataContext()
Private Sub btnLoad_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnLoad.Click
Dim custs = From c In aw.Customers
Me.CustomerBindingSource.DataSource = custs
End Sub
Code snippet CustomersForm.vb
Because the DataContext will still exist, when the binding source navigates to the various
properties, LINQ to SQL will kick in, populating these properties with data. This is much more
scalable than attempting to populate the whole customer hierarchy when the user clicks the button.
618 .
chaPter 28 lAnguAge inTegrATed QuerieS (linQ)
linqPad
While the intent behind LINQ was to make code more readable, in a lot of cases it has
made writing and debugging queries much harder. The fact that LINQ expressions are only
executed when the results are iterated can lead to confusion and unexpected results. One of
the most useful tools to have by your side when writing LINQ expressions is Joseph Albahari’s
LINQPad (www.linqpad.net). Figure 28-26 illustrates how you can use the editor in the
top-right pane to write expressions.
fiGure 28-26
In the lower-right pane you can see the output from executing the expression. You can tweak your
LINQ expression to get the correct output without having to build and run your entire application.
suMMary
In this chapter you were introduced to Language Integrated Queries (LINQ), a significant step
toward a common programming model for data access. You can see that LINQ statements help to
make your code more readable, because you don’t have to code all the details of how the data should
be iterated, the conditional statements for selecting objects, or the code for building the results set.
You were also introduced to the new XML object model, the XML language integration within VB,
how LINQ can be used to query XML documents, and how Visual Studio 2010 IntelliSense enables
a rich experience for working with XML in VB.
summary .
619
Finally, you were introduced to LINQ to SQL and how you can use it as a basic object-relational
mapping framework. Although you are somewhat limited in being able only to map an object to a
single table, it can still dramatically simplify working with a database.
In the next chapter you see how powerful LINQ is as a technology when you combine it with
the ADO.NET Entity Framework to manage the life cycle of your objects. With much more
sophisticated mapping capabilities, this technology will dramatically change the way you will work
with data in the future.
29
The aDo.neT entity
framework
what’s in this chaPter?
.
Understanding the Entity Framework
.
Creating an Entity Framework model
.
Querying Entity Framework models
One of the core requirements in business applications (and many other types of applications)
is the ability to store and retrieve data in a database. However, that’s easier said than done,
because the relational schema of a database does not blend well with the object hierarchies
that we prefer to work with in code. To create and populate these object hierarchies required
a lot of code to be written to transfer data from a data reader into a developer- friendly object
model, which was then usually difficult to maintain. In fact, it was such a source of constant
frustration that many developers turned to writing code generators or various other tools
that automatically created the code to access a database based on its structure. However,
code generators usually created a 1:1 mapping between the database structure and the object
model, which was hardly ideal either, leading to a problem called “object relational impedance
mismatch,” where how data was stored in the database did not necessarily have a direct
relationship with how developers wanted to model the data as objects. This led to the concept
of Object Relational Mapping, where an ideal object model could be designed for working
with data in code, which could then be mapped to the schema of a database. Once the
mapping is complete, the Object Relational Mapper (ORM) framework should take over the
burden of translating between the object model and the database, leaving developers to focus
on actually solving the business problem (rather than focusing on the technological issues of
working with data).
622 .
chaPter 29 The Ado.neT enTiTy FrAmeWork
To many developers, ORMs are the Holy Grail for working with data in a database as objects, and
there’s no shortage of debate over the strengths and pitfalls of the various ORM tools available,
and how an ideal ORM should be designed. We won’t buy into these arguments in this chapter,
but simply look at how to use the ADO.NET Entity Framework — Microsoft’s ORM tool and
framework.
Looking through history, the .NET Framework added a number of means to access data in a
database since its inception, all under the banner of ADO.NET. First, we had low-level access
through SqlConnection (and connections for other types of databases) using means like data
readers. Then we had a higher-level means of accessing data using Typed DataSets. LINQ to SQL
appeared in the .NET Framework 3.5, providing the first built-in way to work with data as objects.
However, for a long time Microsoft did not include an ORM tool in the .NET Framework (despite
a number of earlier attempts to do so with the failed ObjectSpaces). There were already a number
of ORMs available for use with the .NET Framework, with nHibernate and LLBLGen Pro being
among the most popular. Microsoft did eventually manage to release its own, which it called the
ADO.NET Entity Framework, and shipped it with the .NET Framework 3.5 SP1.
The Entity Framework’s eventual release (despite being long awaited) was not smooth sailing
either — with controversy generated before it was even released by a vote of no confidence petition
signed by many developers, including a number of Microsoft MVPs. Indeed, it was the technology
that provided the catalyst leading to the rise of the ALT.NET movement. However, since then there
have been many improvements in the .NET Framework 4’s Entity Framework implementation in
order to reduce these perceived shortcomings.
This chapter takes you through the process of creating an Entity Framework model of a database,
and how to query and update the database via it. The Entity Framework is a huge topic, with entire
books devoted to its use. Therefore, it would be impossible to go through all its features, so this
chapter focuses on discussing some of its core features and how to get started and create a basic
entity model.
The Entity Framework model you create in this chapter will go on to be used in a number of
subsequent chapters in this book where database access is required in the samples.
what is the entity fraMework?
Essentially, the Entity Framework is an Object Relational Mapper. Object Relational Mapping
enables you to create a conceptual object model, map it to the database, and the ORM framework
will take care of translating your queries over the object model to queries in the database, returning
the data as the objects that you’ve defined in your model.
comparison with linq to sql
A common question from developers is regarding the Entity Framework’s relationship with LINQ
to SQL, and which technology they should use when creating data-centric applications. Let’s take a
look at the advantages each have over the other.
What is the entity framework? .
623
LINQ to SQL advantages over the Entity Framework:
.
Easy to get started and query
Entity Framework advantages over LINQ to SQL:
.
Enables you to build a conceptual model of the database rather than purely working with a
1:1 domain model of the database as objects (such as having one object mapped to multiple
database tables, inheritance support, and defining complex properties).
.
Able to generate a database from your entity model.
.
Support for databases other than just SQL Server.
.
Support for many-to-many relationships.
.
Lazy loading and eager loading support.
.
Synchronization to get database updates will not lose your customizations to your model.
.
Will continue to evolve, whereas LINQ to SQL development will from now on be minimal.
entity framework concepts
Here are some of the important concepts involved in the Entity Framework and some of the terms
that are used throughout this chapter:
.
Entity Model: The entity model you create using the Entity Framework consists of three
parts:
.
Conceptual model: Represents the object model, including the entities, their
properties, and the associations between them.
.
Store model: Represents the database structure, including the tables/views/stored
procedures, columns, foreign keys, and so on.
.
Mapping: Provides the glue between the store model and the conceptual model (that
is, between the database and the object model), by mapping one to the other.
Each of these parts is maintained by the Entity Framework as XML using a domain-specific
language (DSL).
.
Entity: Entities are essentially just objects (with properties) to which a database model is
mapped.
.
Entity Set: An entity set is a collection of a given entity. You can think of it as an entity
being a row in a database, and an entity set being the table.
.
Association: Associations define relationships between entities in your entity model, and are
conceptually the same as relationships in a database. Associations are used to traverse the
data in your entity model between entities.
.
Mapping: Mapping is the core concept of ORM. It’s essentially the translation layer from a
relational schema in a database to objects in code.
624 .
chaPter 29 The Ado.neT enTiTy FrAmeWork
GettinG started
To demonstrate some of the various features in the Entity Framework, the example in this section
uses the AdventureWorksLT sample database developed by Microsoft as one of the sample databases
for SQL Server. AdventureWorksLT is a simpler version of the full AdventureWorks database, making
it somewhat easier to demonstrate the concepts of the Entity Framework without the additional
complexity that using the full database would create.
The AdventureWorksLT database is available for download from the CodePlex web site as a
database script here:
http://professionalvisualstudio.com/link/1029A
Adventure Works Cycles is a fictional bicycle sales chain, and the AdventureWorksLT database is
used to store and access its product sales data.
Follow the instructions from the CodePlex web site detailing how to install the database from the
downloaded script in a SQL Server instance (SQL Server Express Edition is sufficient) that is on or
can be accessed by your development machine.
Now move on to creating a project that contains an Entity Framework model of this database. Start
by opening the New Project dialog and creating a new project. The sample project you create in this
chapter uses the WPF project template. You’ll be displaying data in a WPF DataGrid control defined
in the MainWindow.xaml file named dgEntityFrameworkData.
Now that you have a project that will host and query an Entity Framework model, it’s time to create
that model.
creatinG an entity Model
You have two ways of going about creating an entity model. The usual means to do so is to create
the model based on the structure of an existing database; however, with the Entity Framework it
is also possible to start with a blank model and have the Entity Framework generate a database
structure from it.
The sample project uses the first method to create an entity model based on the AdventureWorksLT
database’s structure.
the entity data Model wizard
Open the Add New Item dialog for your project, navigate to the Data category, and select ADO.NET
Entity Data Model as the item template (as shown in Figure 29-1). Call it AdventureWorksLTModel
.edmx.
Creating an entity Model .
625
fiGure 29-1