PREVIEW CONTENT
This excerpt provides early content from a book currently in
development, and is still in draft, unedited format See additional notice below
This document supports a preliminary release of a software product that may be changed substantially prior to final commercial release This document is provided for informational purposes only and Microsoft makes no warranties, either express or implied, in this document Information in this document, including URL and other Internet Web site references, is subject to change without notice The entire risk of the use or the results from the use of this document remains with the user Unless otherwise noted, the companies, organizations, products, domain names, e-mail addresses, logos, people, places, and events depicted in examples herein are fictitious No association with any real company, organization, product, domain name, e-mail address, logo, person, place, or event is intended or should be inferred Complying with all applicable copyright laws is the responsibility of the user Without limiting the rights under copyright, no part of this document may be reproduced, stored in or introduced into a retrieval system, or transmitted in any form or by any means (electronic, mechanical, photocopying, recording, or otherwise), or for any purpose, without the express written permission of Microsoft Corporation
Microsoft may have patents, patent applications, trademarks, copyrights, or other intellectual property rights covering subject matter in this document Except as expressly provided in any written license agreement from Microsoft, the furnishing of this document does not give you any license to these patents, trademarks, copyrights, or other intellectual property
© 2010 Microsoft Corporation All rights reserved
Microsoft, Microsoft Press, Azure, DataTips, Expression, IntelliSense, MSDN, SharePoint, Silverlight, SQL Server, Visual C#, Visual Studio, Windows, Windows Azure, Windows Live and Windows Server are trademarks of the Microsoft group of companies
Trang 3Intraduction
` ‘ne be Mao att
Trang 4use a real application that covers many areas of the product rather than show you many
disjointed little samples This application is named Plan My Night, and we'll describe it in
detail in this Introduction
To help as many developers as we can, we decided to divide this book into three parts:
e = Part | will be for developers moving from Visual Studio 2003
e Part {| will be for developers moving from Visual Studio 2005 e = Part {Il will be for developers moving from Visual Studio 2008
Each part will help developers understand how to use Visual Studio 2010 to create many
different types of applications and unlock their creativity independently of the version they
are using today This book will be focusing on Visual Studio, but we'll also cover many
language features that make the move even more interesting
Each part will follow a similar approach and will include these chapters: e “Business Logic and Data”
e “Designing the Look and Feel” e “Debugging the Application”
For example, Part |, “Moving from Microsoft Visual Studio 2003 to Visual Studio 2010,”
includes a chapter called “From 2003 to 2010: Debugging the Application.” Likewise, Part Il,
“Moving from Microsoft Visual Studio 2005 to Visual Studio 2010,” includes a chapter called “From 2005 to 2010: Debugging the Application.”
Designing the Look and Feel
These chapters will focus on comparing how the creation of the user interface has evolved
through the versions of Visual Studio They pay attention to the design surface, the code
editor, the tools, and the different controls, as well as compare UI validation methods These
chapters also tackle the topic of application extensibility Business Logic and Data
These chapters tackle how the application is structured and demonstrate the evolution of the
tools and language features available to manage data They describe the different application layers They also show how the middle-tier is created across versions and how the application
Trang 6[a Plan My Night - New Itinerary - Windows Internet Explorer E¬5E5==)
=
COU 7 le) http://www planmynight.net:48550/Ttineraries/32 v | %| x | lo Bing 2 vị
Gly Favorites @ Plan My Night - New Itinerary > By ] @ v Pagey Safetyv Toolsy @y »
eur SEARCH | MY PROFILE | MYTTINERARIES | ABOUT Hello PMH New Uses ‘Sign Out |
Itinerary: New Itinerary [Public &È Comments
Addl activities to my finerany @® Leave a comment
Total estimated time: 4h 30m + 2 minutes of tavel time On Monday, January 18, 2010 by PMN New User First Comment! A Volterra Leave a comment ® - Add Comment 7 Se Gi Lư 1 G Sau send to facebook Eclit | Make Private | Email | Print| Shorten URL | Sharg | Rate NHI Bygoex P` = NW Sm St Directions: Driving | \valking yen san St u Locks 4 + Cider tau > ^ http://www.facebook.com/share.php ?u=http%3a%2f%2fwww.planmynight.net%3a485i @ Local intranet | Protected Mode: Off fav Rb% v
Figure I-1 PMN‘s user interface
In its Visual Studio 2010 version, Plan My Night is built with ASP.NET MVC 2.0 using jQuery and Ajax for UI validation and animation It uses the Managed Extensibility Framework (MEF) for extending the capabilities of the application by building plug-ins: for sharing to social networks, printing, emailing, etc We have used the Entity Framework to create the data layer and the Windows Server App Fabric (formerly known as codename Velocity) to cache data in memory sent and obtained from the SQL Server 2008 database
We figure that three pictures are better than one, so take a look at Figure |-2 for a diagram displaying the different parts and how they interact with each other and at Figure I-3 to see
Trang 7an My Night Application
Trang 8(in i™\ (€ ` (Cp Cp Plan My Night 1.0 oO G S 2 3 > Sllu IIS a |e = 7-5 Ww =||> ( J S| |e 1 TO 5 ASP.NET 4.0 — < Ắ ) = ( ASP.NET MVC 2.0 ) gà Server App Fabric (previously codenamed > Velocity) ( SQL SERVER 2008 ) VIS VY NS
Figure I|-3 PMN 1.0 and the different technologies used in building it
Why Should You Move to Visual Studio 2010?
There are numerous reasons to move to Visual Studio 2010 Professional, and before we dive in into the book parts to examine them, we thought it would be good to list a few from a high-level perspective (presented without any priority ordering)
e Built-in tools for Windows 7, including multi-touch and “ribbon” Ul components e Rich new editor built in WPF that you can highly customize to suit how you work
Look below this list at Figure I-4 for a sneak peek e Multi-monitor support
e New Quick Search helping to find relevant results just by quickly typing the first few letters of any method, class, or property
e Great support for developing and deploying Microsoft Office 2010, SharePoint 2010
and Windows Azure applications
Trang 9Improvements to the ASP.NET AJAX framework, core JavaScript Intellisense support, and the inclusion in Visual Studio 2010 of jQuery, the open-source library for DOM interactions
Multi-targeting/multi-framework support Read Scott Guthrie's blog post to get an
understanding of this great feature:
http://weblogs.asp.net/scottgu/archive/2009/08/27/multi-targeting-support-vs- 2010-and-net-4-series.aspx
Support for developing WPF and Silverlight applications with enhanced drag and drop support and data binding Great new enhancements to the designers, enabling a higher fidelity in rendering your controls, which in turn enables you to discover bugs in rendering before they happen at run time (which is a great improvement from previous versions of Visual Studio) New WPF and Silverlight tools will help you to navigate the visual tree and inspect objects in your rich WPF and Silverlight applications
Great support for TFS 2010 (and previous versions) using Team Explorer This enables you to use the data and reports that are automatically collected by Visual Studio 2010 and track and analyze the health of your projects with the integrated reports as well as maintaining your bugs and tasks up-to-date
Integrated support for Test-First Development Automatic test stub generation and a rich unit test framework are two nice test features that developers can take
Trang 10Default.aspxcs
60 PlanMyNight - Microsoft Visual Studio
File Edit View Project Build Debug Team Data Tools ¡E1 | 5è % |3 g2 | GB Gd Gl Se - % Microsoft.Samples.PlanMyNight.Web._Default vÌ © Page_Load(object sender, System.EventArgs e) =|namespace Microsoft.Samples.PlanMyNight.Web = using System.Web; using System.Web.Mvc; using System.Web.UI; = public partial class _Default :
= public void Page_Load(object sender, System.EventArgs e) string originalPath = Request.Path; HttpContext.Current.RewritePath(Request.ApplicationPath, THttpHandler httpHandler = new MvcHttpHandler(); httpHandler ProcessRequest(HttpContext.Current) ; HttpContext.Current.RewritePath(originalPath, false); false); 100% ~ «| » dbl 1! Sa [ai 1| E1ET4 | |š3 ` Error List Description
'Q0Eres If 0 worings f(D O Menage
“@ Error List EÍ Output X4 rínd Symbol Resuit: ĐẾ Te=t Re<ult: Line Column -3 App_Browsers (aj App_Data q Areas q Content q Controllers Helpers q Infrastructure q ViewModels l@ Views Account q Rineraries q Search (49 Shared #3 Web.config fz] Default.aspx 2) Default.aspx.cs (8 Error.htm uf) favicon.ico &Ì Global.asax *8 Global.asax.cs (9) NotFound.htm al Solution Explorer EB Server Explorer Properties Ae L= JLm Js ] 1
Figure |-4 Visual Studio New WPF Code Editor
This is just a short list of all the new features of Visual Studio 2010 Professional; you'll
experience some of them firsthand in this book You can get the complete list of new features
by reading the information presented in those two locations: http://msdn.microsoft.com/en-
us/library/dd547188(VS.100).aspx and http://msdn.microsoft.com/en- us/library/bb386063(VS.100).aspx
Trang 11
Chapter 5
From 2005 to 2010: Business Logic and Data
After reading this chapter, you will be able to
e Use Entity Framework to build a data access layer using an existing database or with the
model first approach
e Generate entity types from the Entity Data Model designer using the ADO.NET Entity Framework POCO templates
e Get data from Web services
e Learn about data caching using the Windows Server AppFabric (formerly known as codename Velocity)
Application Architecture
The PlanMyNight application allows the user to manage his itinerary activities and share them with others The data stored in a SQL Server database Activities are gathered from searches to the Bing Maps Web services
Let's have a look at the high-level block model of the data model for the application, which is shown in Figure 5-1 ` Presentation Layer ASP.NET Pages ị | N v Contract ! Interfaces T I E ` ì Data Access Layer VY J SQL Server
i Bing Map services
Trang 12Defining contracts and entities classes that are cleared of any persistence-related code constraints will allow us to put them in an assembly that has no persistence aware code This will ensure a clean separation between the Presentation and Data layers
Let's identify the contract interfaces for the major components of the PMN application:
e lltinerariesRepository will be the interface to our data store (Microsoft SQL Server database)
e lActivitiesRepository will allow us to search for activities (Bing Map Web services) e ICachingProvider will provide us our data caching interface (ASP.NET Caching or
Windows Server AppFabric Caching)
Note This is not an exhaustive list of the contracts implemented in the PMN application
PMN stores the user’s itineraries into a SQL database Other users will be able to comment and rate each other itineraries Error! Reference source not found.Figure 5-2 shows the tables used by the PMN application Itinerary ltineraryRating Id: bigint IDENTITY Id: bigint IDENTITY
Userld: uniqueidentifier NOT NULL Userld: uniqueidentifier NOT NUL Name: nvarchar(100) NOT NULL ltineraryld: bigint NOT NULL (FK) Created: smalldatetme NOT NULL _— œ| Rating: trnyintNOT NULL Description: nvarchar(1000) NULL *° Timestamp: datetime NOT NULL IsPublic: bit NOT NULL
RatingSum: int NOT NULL
em arrvrrrtrrrrrrr kineraryCommert
Id: bigint IDENTITY
ltineraryld: bigint NOT NULL (FK) RatingCount int NOT NULL mm | | | |
NneraryAciviles 1 —— “® Userld: uniqueidentifier NOT NULL Itineraryld: bigint NOT NULL (FK) Body: nvarchar(4000) NOT NULL Activityld: varchar(250) NOT NULL Timestamp: date NOT NULL
Order: int NOT NULL IpAddress: varchar(16) NOT NULL
EstimatedMinutes: smallint NOT NULL
Typeld: int NOT NULL
State: char(2) NOT NULL ZipCode City: varchar(150) NOT NULL -
Zip: varchar(50) NOT NULL ZipCode: varchar(5) NOT NULL | Location: varchar(20) NULL e: varchar(150)
Figure 5-2 PlanMyNight datase schema
Trang 13PlanMyNight Data in Microsoft Visual Studio 2005
It would be straightforward to create the PlanMyNight in Visual Studio 2005 since it offers all the required tools to help you to code the application However, some of the technologies used back then required you to write a lot more code to achieve the same goals
Let's take a look at how you could create the required data layer in Visual Studio 2005 One approach would have been to write the data layer using ADO.NET DataSet or DataReader directly This solution offers you a great flexibility since you have complete control over the access to the database On the other hand, it also has some drawbacks:
e You need to know the SQL syntax
e All queries are specialized A change in requirement or in the tables will force you to update all the related queries in the code
e You need to map the properties of your entity classes using the column name which is tedious and error prone
e You have to manage the relations between tables yourself _/ PlanMyNightDatabase.cs | PlanMyNightDatabase.xsd ~ xX Microsoft Samples.PlanMyNight.Data.DAL.PlanMyNightDataSet v | YRateltinerary(long itineraryId, Guid userId, byte rating, DateTime timestamp) v ¬ ^ public void RateItinerary(long itineraryId, Guid userId, byte rating, DateTime timestamp) {
const string cmdInsertRating = "INSERT Into ItineraryRating (UserId, ItineraryId, Rating, Timestamp) " +
"VALUES (@UserId, @ItineraryId, @Rating, @Timestamp)"; try { using (SqlConnection sqlConnection = new SqlConnection(global::Microsoft.Samples.PlanMyNight.Data.Pr { using (SqlCommand cmdInsert = sqlConnection.CreateCommand () ) { emdInsert.CommandType = ComtmandType Text; emdInsert.CommandText = cmdInsertRating;
cmdInsert.Parameters.Addd("@UserIa", SqlDbType.UniqueIdentifier) Value = userId; emdInsert.Parameters.Add("@ItinerarylIda", SqlDbType.BigInt).Value = itineraryId; cemdInsert.Parameters.Add("@Rating", SqlDbType.TinyInt) Value = rating;
emdInsert.Parameters.Add("@Timestamp", SqlDbType.DateTime) Value = timestamp; sqlConnection.Open(); emdInsert.ExecuteNonQuery(); sqlConnection.Close(); } } } catch (SqlException) { throw; } v > ‹
Figure 5-3_ ADO.NET Insert query
Trang 14You still need to know the SQL syntax although you have access to the Query builder directly from the DataSet designer
You still need to write specialized SQL queries to match each of the requirements of your data contracts
e You have no control on the generated classes For example, changing the DataSet to add or remove a query for a table will rebuild the generated TableAdapter classes and may change the index used for a query This makes it difficult to write predictable code using these generated items
e The generated classes associated with the tables are persistence aware so you will have to create another set of simple entities and copy the data from one to the other This means
more processing and memory usage
PlanMyNight2005 - Microsoft Visual Studio
File Edit View Project Build Debug Data Tools Test Window Community Help GS oF da |» Gs) > debug > Any cPU - x3] 3 33 se BE1x gì 1 =†1: re vì 1z] Cs sg) PlanMyNightDatabase.cs ’ PlanMyNightDatabase.xsd | ~x | Solution Explorer - 5olution 'PlanMlyHight20 1 ?| — alee 2 lạ; Itinerary IES) 8 ỳ (ez) Solution 'PlanMyNight2005' (5 projects) on a a Id + 3 Tests L ser’ :
9 TtineraryId + @ PlanMyNight Bing
Di 3 Name U serId +i- C1 PlanMyNight.Contracts _
2 Created crag Bod = @ PlanMyNight.Data x Description /2gycomment, care l#i- Sa) Properties s 1sPublic An 2 (<j References — RatingCount ae # Caching | RatingSum (SMe ea orc = By Dat
Rating Fill, GetData () Ị 2) ItineraryTableAdapter.cs ‘a TtineraryTableAdapter IES] su FilByItineraryId,GetDataByItineraryId (@itinerary n PlantivNightDatabase xsd
5) app.config S1 Fil,setData () ® ‹#} BingActivitiesRepository.cs UY DeleteById (@Original_Id) œ) ItinerariesRepository.cs 2u FillByActivity (@Activity_Id) raryactivities_I a ra œ) ReferenceRepository.cs
sa FilByCity (@Type_Id, @5tate, @City) mm bung 4 (3 PlanMyNight.web
2) FilById (@Id) v Y Activityd Order EstimatedMinutes Fk _ItineraryRating_Itinerary Typeld g State City Zip Latitude TtineraryId Longitude
| Rating ‘& ItineraryActivitiesTableAdapter
Timestamp Fill, GetData (} Properties wh PlanMyNightDataSet DataSet x ay Fill, GetData () @:: [A | 1 24 FilByLlseranditinerary (@user _Id, @itinerary Lá — > Name PlanMyNightDataSet = "Name | Name of the Dataset class ‹ | (3 Emor List |SB{ Find Results 1 | 43 Find Symbol Results 2] Test Results Ready
Figure 5-4 Dataset designer in Visual Studio 2005
In the next sections of this chapter, you are going to explore some of the new features of
Trang 15Data with the Entity Framework in Visual Studio 2010 The ADO.NET Entity Framework (EF) allows you to easily create the data access layer for an application by abstracting the data from the database and exposing a model closer to business requirement of the application The EF has been considerably enhanced in the NET Framework 4 release
See Also The MSDN Data Developer Center offers a lot of resources about the ADO.NET Entity Framework in NET 4
You are going to use the PlanMyNight project as an example of how to build an application
using some of the features of the EF The next two sections demonstrate two different
approaches to generate the data model of PMN In the first one, you are going to let the EF generate the Entity Data Model (EDM) from an existing database In the second part, you will use a Model First approach where you first create the entities from the EF designer and generate the Data Definition Language (DDL) scripts to create a database that can store your
EDM
EF: Importing an Existing Database
You are going to start with an existing solution that already defines the main projects of the PMN application If you have installed the companion content at the default location you will find the solution at this location: %userprofile%\Documents\Microsoft Press\Moving to Visual Studio 2010\Chapter 5\Code\ExistingDatabase Double-click the PlanMyNight.sln file This solution includes all the projects you can see in Figure 5-5
e PlanMyNight.Data: Application data layer PlanMyNight.Contracts: Entities and Contracts PlanMyNight.Bing: Bing Map Services
PlanMyNight.Web: Presentation Layer
Trang 16Solution Explorer vax a4 Solution ‘PlanMyNight’ ( projects) 4 Gl PlanMyNightAppFabricCaching =a Properties (a References 4 Gñ]PlanMyNight.Bing Sal Properties Sl References 4G PlanMyNight.Contracts =a Properties (aj References 4 @PlanMyNight.Data Sal Properties {ay References 4 (QPlanMyNightWeb Sal Properties (aj References S App.Data (Gi Controllers (Gi Models (i Scripts (Views 4) Global.asax 3 Web.config
Figure 5-5 PlanMyNight Solution
The EF allows you to easily import an existing database Let's walk through this process The first step is to add an EDM to the PlanMyNight.Data project Right-click the
PlanMyNight.Data project, select Add, and then New Item Select the ADO.NET Entity Data Model item and change its name to PlanMyNight.edmx, as shown in Figure 5-6
‘Add New Item - PlanMyNight Data les)
Installed Templates sortby Search Istaled Templates 2 2 Vol O# em: Code ADO.NET Entity Data Model Visual Ci tems Type: Visual C#Te Visual Ctems
A projectite for creating an ADO.NET
Date General DataSet Visual C# Items Entity Data Model
Web
Windows Forms LINQ to SQL Classes Visual C# Items WPF
Reporting Sivetight Local Database Visual Ci Items:
‘Workflow Local Database Cache Visual C# Items
Senice-based Database Visual CH ems YOM File Visual C tems YL Schema Visual C tems
Trang 17The first dialog of the Entity Data Model Wizard allows you to choose the model content You are going to generate the model from an existing database Select Generate From Database then click Next
You need to connect to an existing database file Click New Connection and select the %userprofile%\Documents\Microsoft Press\Moving to Visual Studio 2010\Chapter 5\ExistingDatabase\PlanMyNight.Web\App_Data\PlanMyNight.mdf file
Entity Data Model Wizard Ik) Connection Properties
Enter information to connect to the selected data source or click "Change" to choose a different data source and/or provider
Microsoft SQL Server Database File (SqlClient)
Database file name (new or existing)
DlanMyNight.Web\pp_Data\PlanMyNight.mndf Log on to the server
© Use Windows Authentication Use SOL Server Authentication
‘Save my password
Figure 5-7 EDM Wizard Database Connection
Leave the other fields in the form as is for now and click Next
Trang 18Entity Data Model Wizard x
iL Choose Your Database Objects =2
Which database objects do you want to include in your model?
4 7) Tables a (JE5 aspnet_Applications (dbo)
(JE5 aspnet_Membership (dbo) “J aspnet_Profile (dbo)
SS aspnet_SchemaVersions (dbo)
(JE3 aspnet_Users (dbo) (VI] Rinerary (dbo) (V)5 ItineraryActivities (dbo) VÌ] RinerawyCormnment (dbo} ⁄|] EineraryRating (dbo) (JE5 sysdiagrams (dbo) (V5 ZipCode (dbo) 4 [| Views i5] UserProfile (dbo) j1 vưự_asnnet_Ânplicatians (dbo) | =) vuv_aspnet_MembershipUsers (dbo) [ j vw_aspnet_Profiles (dbo) (FS) ww_aspnet_Users (dbo) 4 |Z) Sp Stored Procedures
ES Lasnnet AnvDatalnTahles fdhoi >é
(¥) Pluralize or singularize generated object names mW ¥) Include foreign key colurnns in the model Model Namespace: Entities
Figure 5-8 EDM Wizard: Choose the database objects
Click Finish to generate your EDM
Fixing the Generated Data Model
You now have a model representing a set of entities matching your database The wizard has generated all the navigation properties associated with the foreign keys from the database The PMN application only requires the navigation property associated with the
Trang 19
45 Rinerary a) 4g, MineraryActivity (A) 45 ZipCode a)
© properties © properties Properties
®a 8 Rineranjd 9 ZipCodet
BP Userid © Activtyid Bcity CF Name Forder oF state
Created (F EstimatedMinutes © Navigation Properties Description ñ | sa “#fbPublic OF State RatingCount city atingSum Zp oF Rating (CP Latitude = Navigation Properties [Longitude
Activities & Navigation Properties va 1 C2; TinwayCom | ` = Properties © Properties yi td Fitinerarid SP Userd SP Userld 'Ẩftineranjd '# Body oF Rating (FTimestamp SP Timestamp “SP IpAddress © Navigation Properties Navigation Properties
Figure 5-9 Model imported from the PlanMyNight database
You will notice that one of the properties of the ZipCode entity has been generated with the name ZipCodel Let's fix the property name by double-clicking it Change the name to Code, as shown in Figure 5-10 Í 2¿_ Zipcode © Pro s OF state © Navigation Properties
Figure 5-10 ZipCode entity
Build the solution by pressing Ctrl+Shift+B When looking at the output window, you will notice two messages from the generated EDM You can discard the first one since the Location column is not required in PMN The second message reads:
The table/view ‘dbo.UserProfile' does not have a primary key defined and no valid primary key could be inferred This table/view has been excluded To use the entity, you will need to review your schema, add the correct keys, and uncomment it
Trang 20You will have to modify the EDM manually fix the UserProfile view mapping
From the project explorer, right-click the PlanMyNight.edm«x file and then select Open With Choose XML (Text) Editor from the Open With dialog as shown in Figure 5-11 This will open the XML file associated with your model
Open With - PlanMyNight.edrnx 9
Choose the program you want to use to open this file: ADO.NET Entity Data Model Designer (Default) Automatic Editor Selector XML) XML (Text) Editor with Encoding Source Code (Text) Editor Add | Source Code (Text) Editor With Encoding Set as Default | HTML Editor HTML Editor with Encoding Binary Editor Resource Editor (cee
Figure 5-11 Open PlanMyNight.emdx in the XML Editor
Note You will get a warning stating that the PlanMyNight.edmx file is already open Click Yes to close it
The generated code was commented out by the code generation tool because there was no primary key defined To allow you to use the UserProfile view from the designer, you need to uncomment the UserProfile entity type and add the Key tag to it Search for UserProfile in the file Uncomment the entity type, add a key tag and set its name to UserName and make the UserName property not nullable Refer to Listing 5-1 to see the updated EntityType
Listing 5-1 UserProfile Entity Type XML Definition
<EntityType Name="UserProfi le">
<Key>
<PropertyRef Name="UserName" /> </Key>
<Property Name="UserName"” Type="uniqueidentifier” Nullable="false"” /> <Property Name="FullName" Type="varchar" MaxLength="500" />
<Property Name="City" Type="varchar" MaxLength="500" /> <Property Name="State" Type="varchar" MaxLength="500" /> <Property Name="PreferredActivitylypeId" Type="int" /> </EntityType>
Trang 21You will need to define an entity set for the UserProfile type so that it can map the entity type to the store schema Open the PlanMyNight.edmx file in the XML editor so that you can
define an entity set for UserProfile At the top of the file, just above the Itinerary entity set,
add the XML code shown in Listing 5-2
Listing 5-2 UserProfile EntitySet XML Definition
<EntitySet Name="UserProfile" EntityType="Entities.Store.UserProfile" store: Type="Views" store:Schema="dbo" store:Name="UserProfile"> <DefiningQuery> SELECT [UserProfile].[UserName] AS [UserName], [UserProfile].[FullName] AS [FullName], [UserProfile].[City] AS [City], [UserProfile].[State] AS [State], [UserProfile].[PreferredActivityTypelId] as [PreferredActivityTypeld] FROM [dbo].[UserProfile] AS [UserProfile] </DefiningQuery> </EntitySet>
Save the EDM XML file and reopen the EDM Designer The Figure 5-12 shows the UserProfile view in the Entities.Store section of the Model Browser
Trang 22Figure 5-12 Model Browser with the UserProfile view
Now that the view is available in the store metadata, you are going to add the UserProfile entity and map it to the UserProfile view Right-click in the background of the EDM Designer, select Add and then Entity Add Entity Bo |S Properties Entity name: UserProfile Base type: (None) = Entity Set: UserProfiles Key Property ¥) Create key property Property name: UserName Property type: Guid vị mm
Figure 5-13 Add UserProfile entity dialog
Complete the dialog as shown in Figure 5-13 and click OK to generate the entity
You will need to add the remaining properties: City, State, and PreferredActiviyTypeld To do so, right-click the UserProfile entity, select Add, then Scalar Property Once the property is added, set the Type, Max Length, and Unicode field value Table 5-1 shows the expected
values for each of the field
Table 5-1 UserProfile Entity Properties
Name Type Max Length Unicode
FullName String 500 False
City String 500 False
State String 500 False
PreferredActivityTypeld Int32 NA NA
Trang 23
Rename Cut Ctrl +X | Copy Ctrl+C | Paste Ctrl +V ữ % Delete Del x | Collapse Table Mapping Stored Procedure Mapping Ez Bl
Show in Model Browser Update Model from Database Generate Database from Model Add Code Generation Item Validate
(=) Properties Alt+Enter
Figure 5-14 Table Mapping menu item
Then select the UserProfile view from the dropdown box as shown in Figure 5-15 Ensure that all the columns are correctly mapped to the entity properties The UserProfile view of our store is now accessible from the code through the UserProfile entity
Mapping Details - UserProfile ~a~x
Column Operator Value / Property = 4 Tables 4 [Maps to UserProfile <Add a Condition> 4 (@ Column Mappings UserName : uniqueidentifier (2) FullNare : varchar (2) City: varchar [2] State : varchar (2) PreferredActivityTypeld ; int E] <Add a Table or View> ®9 UserName : Guid oF FullName : String } City: String oF State : String OF PreferredActivityTypeld : Int32 titi?
Figure 5-15 UserProfile Mapping details
Stored Procedure and Function Imports
The Entity Data Model Wizard has created an entry in the storage model for the
Trang 24Function Import Name: RetrieveltinerariesWithinArea Stored Procedure Name: RetrieveltinerariesWithinArea ’ Returns a Collection Of © None © Secalars: - © Complex Update © Entities: [Itinerary v
Stored Procedure Column Information Get Column Information
Click on "Get Column Information” above to retrieve the stored
procedure’s schema Once the schema is available, click on "Create New Complex Type” below to create a compatible complex type You can
also always update an existing complex type to match the returned schema The changes will be applied to the model once you click on OK Create New Complex Type
Figure 5-16 Add Function Import dialog
The RetrieveltinerariesWithinArea function import was added to the Model Browser as shown in Figure 5-17
Model Browser vax
Type here to search ae 4a PlanMyNight.edmx 4 [a] Entities (Gi Entity Types (@ Complex Types (@ Associations
4 (a) EntityContainer: PlanMyNightEntities (Gi Entity Sets
Trang 25You can now validate the EDM by right-clicking in the design surface and selecting Validate There should be no error or warning
EF: Model First
In the last section, we saw how to use the EF designer to generate the model by importing an existing database The EF Designer in Visual Studio 2010 also supports the ability to generate the Data Definition Language (DDL) file that will allow you to create a database based on your entity model
You can start from empty model by selecting the Empty model option from the Entity Data Model Wizard
Entity Data Model Wizard
iL =~ Choose Model Contents
What should the model contain?
Chica Ernipty model
fram d
Creates an ernpty model as a starting point for visually designing a conceptual model from the toolbox Classes are generated from the model when the project is compiled, You can specify a database connection
later to map the conceptual model to the storage model
Figure 5-18 EDM Wizard: Empty Model
Open the PMN solution at this location: %userprofile%\Documents\Microsoft Press\Moving to Visual Studio 2010\Chapter 5\Code\ModelFirst by double-clicking the PlanMyNight.sln file The PlanMyNight.Data project from this solution already contains an EDM file named
PlanMyNight.edmx with some entities already created These entities are matching the data
schema from Figure 5-2
Trang 26as shown in Figure 5-19 Rename the entity to ZipCode Rename the /d property to Code and change its type to String
eo PlanMyNight - Microsoft Visual Studio c:||-en- || File Edit View Project Build Debug Team Data Test Tools Window Help
¡ly | š 3 39x -| È |lpebug x|| Ge Bl@o-~ ;¡ 3 8, R- A+ fš|E‡zE| s 3 |C1§423 gi L2 £1 3S) ;
Toolbox baad PlanMtyNight.edmmx” x y_ ŠSolution Explorer Mi o9
4 Entity Frarnework 7c E1: Sử = “2 ZipCode za 4 Itinerary  2 ItineraryComment (A 7 =] 2 2]
| N Pointer | lod Solution 'PlanMyNight' (5 projects)
L Association © properties = Properties =I Properties 4 Gñ] PlanMyNight.AppFabricCaching
Enti =a] P rti
CN Lạ Inheritance oF City 23 F Userld Đi FP itineraryid 3 ial References
4 General — CF State SF Name : CF Userld : 2 a PlanMyNight Bing (Sa) Properties
= Navigation Properties F Created SSŸ Body a “Sj References
There are no usable “Description Timestamp ~ - controls in this group r#kPubli "8 IpAdd 4 Gỗ PlanMyNight.Contracts Drag an item onto this - 2 ụ iG p— (Sa) Properties
text to add it to the os ene Ount =| Navigation Properties <j References
toolbox, “SŸ RatingSum 4 @&PlanMyNight.Data
=F Rating (Sa) Properties 42 TtineraryRating zx yj References ä PlanMwNight.edmx = Navigation Properties = Properties 3) PlanMyNight.Designer.cs m==>=em 241d (@ PlanMyNight.Web 4¿ MineraryActivity (Â FP Userld el Solution [LEER sas lái tele Br #SƑ IineraryId : ˆ = Properties Rating Propertties x
29 Itineraryld FP Timestamp PlanMyNight.ZipCode.Code Property x 85 Activityid = Navigation Properties 2 a | S|
Sf Order Unicode False ^ “8Ÿ EstimatedMinutes 4
F State
ci Concurrency Mod: None Ta Default Value (None)
Latitude >» Documentation = F Longitude Entity Key True LŸ FT ypeld Name Code NỈ
= Navigation Properties Toy Name kì
ot
VỆ The name of the property
32 Toolbox ESSE san « m
B Output ÍẾ Pending Changes WM Error List
ĐT ho
Figure 5-19 Entity Model designer
You need to add the City and State properties to the entity Right-click the ZipCode entity, select Add and then Scalar Property Ensure that each property has the values shown in Table 5-2 Table 5-2 ZipCode Entity Properties
Name Type Fixed Length Max Length | Unicode
Code String False 5 False
City String False 150 False
State String False 150 False
Trang 27
Í Add Association oes) Association Name: FK {tineraryCommentltinerary End End Entity: Entity: [ItineraryComment Mi [Itinerary | Multiplicity: Multiplicity: [* (Many) +| [1(One M |_| Navigation Property: |_| Navigation Property: Itinerary ItineraryComments
| Add foreign key properties to the ‘ItineraryComment' Entity ItineraryCormment can have 1 (One) instance of Itinerary Itinerary can have * (Many) instances of ItineraryComment,
Figure 5-20 Add Association dialog for FK_ItineraryCommentitinerary
Set the association name to FK_ItineraryCommentitinerary and the select the entity and the multiplicity for each end, as shown in Figure 5-20 Once the association is created, double- click association line to set the Referential Constraint as shown in Figure 5-21 Í Referential Constraint |-9-||ke Principal: Itinerary v | OK Dependent: ItineraryComment Principal Key Dependent Property Id Itineraryld
Figure 5-21 Association Referential Constraint dialog
Repeat the same operations for the FK_ItineraryltineraryRating association by setting the first end to ItineraryRating
Trang 28Add Association Dom Association Name: FkK_ItineraryActivityltinerary End End Entity: Entity: (Iinera tyctivity xv | [Itinerary v Multiplicity: Multiplicity: [* (Many) +| [1(One) vị (| Navigation Property: \¥| Navigation Property: Itinerary Activities || Add foreign key properties to the 'ItineraryActivity' Entity
ItineraryActivity can have 1 (One) instance of Itinerary +
Itinerary can have * (Many) instances of ItineraryActivity, Use
Itinerary.Activities to access the Itineraryétctivity instances,|
Figure 5-22 Add Association dialog for FK_ItineraryActivityltinerary
Generating the Database Script from the Model
Your data model is now completed but there is no mapping or store associate to it The EF designer offers the possibility to generate a database script from our model
Right-click in the designer surface and choose Generate Database From Model as shown in Figure 5-23
= = State oF Created ma Bady
= Navigation Properties mạ Description FP Timestan FP IsPublic FP IpAddres: ©} RatingCount © Navigation P Add » Diagram » a Zoom ' 2 Ttinerary/ Grid " p : › , = Properties I »
Scalar Property Format PF kinerar
Select All 29 Activity
Mapping Details Z8 Order
[a] Model Browser =F Estimat
E tate
Hs
Update Model from Database city
Generate Database from Model Zip
Add Code Generation Item “SP Latitud
ST Longit
Validate EF Longit
- PF Typeld
‘=) Properties hy me epee Alt+Enter El Navigatior
Trang 29The Generate Database Wizard requires a data connection The wizard will use the connection information to translate the model types to the database type and to generate a DDL script targeting this database
Select New Connection and make sure the Data Source is set to Microsoft SQL Server File Click Browse and select the database file located %userprofile%\Documents\Microsoft Press\Moving to Visual Studio 2010\Chapter 5\Code\ModelFirst\Data\PlanMyNight.mdf
Œ >
Connection Properties eX)
Enter information to connect to the selected data source or click "Change" to choose a different data source and/or provider Data source:
Microsoft SQL Server Database File (SqlClient)
Database file name (new or existing):
ents\Source\Data\ModelFirst\PlanMyNight.mdf Browse Log onto the server
@ Use Windows Authentication Use SOL Server Authentication
Save my password
Figure 5-24 Generate script database connection
Trang 30Generate Database Wizard ạ Sum mary and Settings I Save DDL As: PlanMyNight.edmx.sql DDL Ww Entity Designer DDL Script for SQL Server 2005, 2008, and Azure Date Created: 02/03/2010 22:58:49 Generated from EDMX file: C:\Users\pascalp\Documents\Visual Studio 2010\Projects \Chapter5\PlanMyNight.Data\PlanMyN}ght.edmx SET QUOTED_IDENTIFIER OFF: SO USE [PlanMyNight]; GO IF SCHEMA_ID(N'dbo') IS NULL EXECUTE(N'CREATE SCHEMA [dbo’); GO Dropping existing FOREIGN KEY constraints < Previous Cancel Figure 5-25 Generated T-SQL file
The EDM is also updated to ensure your newly created store is mapped to the entities You could now use the generated DDL script to add the tables to the database You now have a data layer that expose strongly typed entities that you can use in your application
Important Generating the complete PMN database would require adding the remaining tables, stored procedure and triggers used by the application Instead of performing all these operations, we will go back to the solution we had at the end of the “EF: Importing an Existing Database” section
POCO Templates
The EDM Designer uses T4 templates to generate the entities code So far, we have let the designer create the entities using the default templates You can take a look at the code generated by opening the PlanMyNight.Designer.cs file associated to PlanMyNight.edmx The generated entities are based on the EntityObject type and decorated with attributes to allow the EF to manage them at run time
Trang 31The EF also supports POCO entity types POCO classes are simple objects with no attributes or base class related to the framework (Listing 5-3, in the next section, shows the POCO class for the ZipCode entity.) The EF uses the names of the types and the properties of these objects to map them to the model at run time
Note POCO stands for Plain-Old CLR Objects
ADO.NET POCO Entity Generator
Let's re-open the %userprofile%\Documents\Microsoft Press\Moving to Visual Studio 2010\Chapter 5\Code\ExistingDatabase\PlanMyNight.sin file
Select the PlanMyNight.edmx file, right-click in the design surface and choose Add Code Generation Item This will open a dialog shown in Figure 5-26 where you can select the template you want to use Select the ADO.NET POCO Entity Generator template and name it PlanMyNight.tt Then click the Add button
Add New Item - PlanMyNight.Data
Installed Templates Sort by: | Default 3 Bị Search Installed Templates 2
4 Visual C# Items - Type: Visual C¥ It i
Code 4 ADO.NET EntityObject Generator Visual C# Items yPE V05 ems
D A project item to generate a strongly- ata - - typed ObjectContext class and entity General 4, ADO.NET POCO Entity Generator Visual C# Items classes with persistence ignorance Web ve Windows Forms NX ADO.NET Self-Tracking Entity Generator Visual C# Items 2 WPF Reporting Silverlight Workflow Online Templates Name: PlanMyNight.tt An
Figure 5-26 Add New Item dialog
Two files have been added to your project, as shown in Figure 5-27 These files replace the default code-generation template and the code is no longer generated in the
Trang 32is! PlanMyNight.AppFabricCaching (I PlanMyNight.Bing G] PlanMyNight.Contracts GÏ PlanMyNight.Data =a) Properties b s3j Refererices =} App.Config 4 (2) PlanMyNight.Context.tt 2) PlanMyNight.Context.cs (& PlanMyNight.edmx 4 3) PlanMyNight.tt 2) Itinerary.cs ‘®) ItineraryActivity.cs ‘®) ItineraryComment.cs 2) ItineraryRating.cs '® PlanMyNight.cs 2) UserProfile.cs 2) ZipCode.cs (& PlanMyNight.Web
Figure 5-27 Added templates
The PlanMyNight.tt template produces a class file for each entity in the model Listing 5-3 shows the POCO version of the Z/pCode class
Listing 5-3 POCO version of the ZipCode Class
namespace Microsoft.Samples.PlanMyNight Data {
public partial class ZipCode {
#region Primitive Properties public virtual string Code { get; set; } public virtual string City { get; set; } public virtual string State { get; set; } #endregion
Tip C# 3.0 introduced a new feature called “automatic properties” The backing field is created at compile time if the compiler finds empty get or set blocks
The other file, PlanMyNight.Context.cs, generates the ObjectContext object for the PlanMyNight.edmx model This is the object we are going to use to interact with the
Trang 33Tip The POCO templates will automatically update the generated classes to reflect the changes to your model when you save the edmx file
Moving the Entity Classes to the Contracts Project
We have designed the PMN application architecture to ensure that the presentation layer was persistence ignorant by moving the contracts and entity classes to an assembly that has no
reference to the storage
Visual Studio 2005 Even though it was possible to extend the XSD processing with code generator tools, it was not easy and you had to maintain these tools The EF uses T4 templates to generate both the database schema and the code These templates can easily be customized to your needs
The ADO.NET POCO templates split the generation of the entity classes to a separate template allowing us to easily move these entities to a different project
You are going to move the PlanMyNight.tt file to the PlanMyNight.Contracts project By right-clicking PlanMyNight.tt file, select Cut Right-click the Entities folder in the
PlanMyNight.Contracts project and select Paste Solution Explorer vax sả Lan e]| s3 Gñ] PlanMyNight.AppFabricCaching GÏ PlanMyNight.Bing 4 (4 PlanMyNight.Contracts =a) Properties <j References Ca Data 4 (& Entities 4 2) PlanMyNight.tt 2) Itinerary.cs ‘®) ItineraryActivity.cs 2) ItineraryComment.cs ‘®) ItineraryRating.cs &) PlanMyNight.cs 2) UserProfile.cs 2) ZipCode.cs 4 @& PlanMyNight.Data =a) Properties Sj References (gj Caching => App.Config 4 3) PlanMyNight.Context.tt 2) PlanMyNight.Context.cs “4 PlanMyNight.edmx (@ PlanMyNight.Web =
Figure 5-28 POCO Template moved to the Contracts Project
The PlanMyNight.tt template relies on the metadata from the EDM model to generate the entity type’s code You need to fix the relative path used by the template to access the EDMX
file
Open the PlanMyNight.tt template and locate the line:
Trang 34Fix the file location so it points to the PlanMyNight.edmx file in the PlanMyNight.Data project:
string inputFile = @" \ \PlanMyNight.Data\PlanMyNight.edmx";
The entity classes are regenerated once you save the template
You also need to update the PlanMyNight.Context.tt template since the entity classes are now
in the Microsoft Samples PlanMyNight.Entities namespace instead of the
Microsoft Samples PlanMyNight.Data namespace Open the PlanMyNight.Context.tt file and update the using section to include the new namespace:
using System;
using System.Data.Objects; using System.Data.EntityClient;
using Microsoft.Samples.PlanMyNight.Entities;
Build the solution with Ctrl+Shift+B The project should now compile successfully
Getting It All Together
Now that you have created the generic code layer to interact with your SQL database, you are ready to start implementing the functionalities specific to the PMN application In the next
sections, you are going to walk through this process, briefly look at the getting data from the Bing Maps services and get a quick introduction to the Windows Server AppFabric Caching feature used in PMN
There is a lot of plumbing pieces of code required to get this all together To simplify the
process, you are going to use an updated solution where the contracts, entities and most of the connecting pieces to the Bing Maps services have been coded The solution will also include the PlanMyNight.Data.Test project to help you validate the code from the
PlanMyNight.Data project
Note Testing in Visual Studio 2010 will be covered in Chapter 7
Getting Data from the Database
At the beginning of this chapter, we have decided to group the operations on the Itinerary entity into the IltinerariesRepository repository interface Some of these operations are:
e Searching for Itinerary by Activity
Trang 35Let's take a look at the corresponding methods in the lltinerariesRepository Interface: e SearchByActivity will allow searching for itineraries by activity and returning a page of data e SearchByZipCode will allow searching for itineraries by zip code and returning a page of data e SearchByRadius will allow searching for itineraries from a specific location and returning a page of data
e Add will allow to add itinerary to the database
Open the PMN solution at this location: %userprofile%\Documents\Microsoft Press\Moving to Visual Studio 2010\Chapter 5\Code\Final by double-clicking the PlanMyNight.sIn file Select the PlanMyNight.Data project and open the ItinerariesRepository.cs file This is the [ItinerariesRepository interface implementation Using the PlanMyNightEntities Object
Context you have generated earlier, you will be able to write LINQ queries against your model and the EF will translate these queries to native T-SQL that will be executed against the database
Note LINQ stands for Language Integrated Query and was introduced in the Net Framework 3.5 It adds native data querying capability to the NET Framework so that you don't have to worry about learning or maintaining custom SQL queries LINQ allows you to use strongly typed objects and the Visual Studio Intellisense lets you select the properties or methods that are in the current context as shown in Figure 5-29 To learn more about LINQ, visit the NET Framework Developer Center public PagingResult<Itinerary> SearchByActivity(string activityId, int pageSize, int pageNumber) rf + using (var ctx = new PlanMyNightEntities()) 5 v ctx.ContextOptions.ProxyCreationEnabled = false; var query = from itinerary in ctx.Itineraries.Include("Activities") where itinerary.Activities.Any(t => t.| ` FP Activity ^ ; “8Ÿ Activityld | string ItineraryActivity.Activityld &F City % Equals © EstimatedMinutes © GetHashCode © GetType ɬn Itineraryld * Latitude
Figure 5-29 Intellisense support for LINQ queries
Navigate to the SearchByActivity function definition This method must return a set of
Trang 36Visual Studio 2005 Implementing each methods to retrieve the itinerary in Visual Studio 2005 would have required writing tailored SQL With the EF and LINQ, any query becomes trivial and changes can be easily implemented at the code level!
Using standard LINQ operators, you can implement the SearchByActivity as shown in Listing 5-4 Add the highlighted code to the SearchByActivity method body
Listing 5-4 SearchByActivity Implementation
public PagingResult<Itinerary> SearchByActivity(string activityId, int pageSize, int pageNumber) { using (var ctx = new PlanMyNightEntities()) { ctx.ContextOptions.ProxyCreationEnabled = false;
var query = from itinerary in ctx.Itineraries.IncludeC("Activities”)
where itinerary.Activities.Any(t = t.ActivityId == activityId) && itinerary IsPublic orderby itinerary.Rating select itinerary; return PageResults(query, pageNumber, pageSize) ; } }
Note The result paging is implemented in the PageResults method
private static PagingResult<Itinerary> PageResults(IQueryable<Itinerary> query, int page, int pageSize) { int rowCount = rowCount = query.Count(Q); if (pageSize > 0) { query = query.Skip((page - 1) * pageSize) Take (pageSize) ; } var result = new PagingResul t<Itinerary> (query ToArray()) { PageSize = pageSize, CurrentPage = page, TotalItems = rowCount }3 return result; }
Trang 37The SearchByZipCode function method is similar to the SearchByActivity method but it also adds a filter on the Zip Code of the activity Here again, LINQ support makes it easy to implement as shown in Listing 5-5 Add the highlighted code to the SearchByZipCode method body
Listing 5-5 SearchByZipCode lmplementation
public PagingResult<Itinerary> SearchByZipCodeCint activitylTypeld, string zip, int pageSize, int pageNumber)
{
using (var ctx = new PlanMyNightEntities(Q)) {
ctx.ContextOptions.ProxyCreationEnabled = false;
var query = from itinerary in ctx.Itineraries.Include("Activities”)
where itinerary Activities.Any(t = t.TypeId == activityTypelId && t.Zip == zip)
&& itinerary IsPublic orderby itinerary.Rating select itinerary;
return PageResults(query, pageNumber, pageSize);
The SearchByRadius function calls the RetrieveltinerariesWithinArea import function that was mapped to a stored procedure It then loads the activities for each itinerary found You can copy the highlighted code in Listing 5-6 to the SearchByRadius method body in the ItinerariesRepository.cs file
Listing 5-6 SearchByRadius |mplementation
public PagingResult<Itinerary> SearchByRadiusCint activityTypeId, double longitude, double latitude, double radius, int pageSize, int pageNumber)
{
using (var ctx = new PlanMyNightEntitiesQ) {
ctx.ContextOptions.ProxyCreationEnabled = false; // Stored Procedure with output parameter
var totalOutput = new ObjectParameter("total"”, typeofCint));
var items = ctx.RetrieveItinerariesWithinArea(activityTypeld, latitude, longitude, radius, pageSize, pageNumber, totalOutput) ToArray();
foreach (var item in items)
{
item Activities AddRange(this.Retrieve(item.Id) Activities) ;
Trang 38int total = totalOutput.Value == DBNul1.Value ? 0 : Cint)totalOutput.Value; return new PagingResult<Itinerary>(Citems) { TotalItems = total, PageSize = pageSize, CurrentPage = pageNumber ‡;
The Add method allows adding Itinerary to the data store Implementing this functionality becomes trivial since our contract and our Context Object are using the same entity object Copy and paste the highlighted code in Listing 5-7 to the Add method body
Listing 5-7 Add Implementation
public void Add(Itinerary itinerary) { using (var ctx = new PlanMyNightEntities(Q)) { ctx.Itineraries.AddObject(itinerary); ctx SaveChanges() ; } }
Here you have it! You have been able to complete the /tinerariesRepository implementation using the Context Object generated using the EF designer Run all the tests in the solution by pressing CTRL+R, A The tests related to the /tinerariesRepository should all succeed
Getting Data from the Bing Maps Web Services
PMN relies on the Bing Maps services to allow the user to search for activities to add to its itineraries To get a Bing Maps Key to use in the PMN application, you need to create a Bing Maps Developer Account You can create a free developer account on the Bing Maps Account
Center
See Also Microsoft Bing Maps Web Services is a set of programmable SOAP services that allow you to match addresses to the map, search for points of interest, integrate maps and imagery, return driving directions, and incorporate other location intelligence into your Web application You can learn more about these services by visiting the site for the Bing Maps Web
Services SDK
Trang 39bring up the Add Web Reference Dialog and then add a reference to an ASMX Web service to your project
Add Web Reference aE Navigate to a web service URL and click Add Reference to add all the available services
@ Back i]
URL: | th.net/webservices/v1/metadata/geocodeservice/geocodeservice.wsdll vị Boo
43 on en men’ Web services found at this URL:
GeocodeService” Description Tesi ervice Found: : Methods - geocodeservice = Geocode () = ReverseGeocode ( ) Web reference name: GeocodeService Add Reference Cancel
Figure 5-30 Visual Studio 2005 Add Web Reference dialog
Introduced in the NET Framework 3.0, the Windows Communication Foundation (WCF) Services brought the ASMX Web services and other communication technologies to a unified programming model
Visual Studio 2010 provides tools for working with Windows Communication Foundation (WCF) Services You can bring the new Add Service Reference dialog by right-clicking on a project node and selecting Add Service Reference as shown in Figure 5-31 In this dialog, you first need to specify the service metadata address in the Address field and then click Go to view the available service endpoints You can then specify a Namespace for the generate code and then click OK to add the proxy to your project
Trang 40
Figure 5-31 Add Service Reference dialog
Tip The Discover button will look for WCF services in the current solution
See Also The Advanced button brings the Service Reference Settings dialog This dialog lets you tweak the configuration of the WCF service proxy You can add the Net Framework 2.0 style reference by using the Add Web Service button To learn more about these settings, visit the MSDN - Configure Service Reference Dialog Box
The generated WCF proxy can be used in the same way you will have used the ASMX style proxy as shown in Listing 5-8
Listing 5-8 Using a Web Service Proxy
public BingCoordinate GeocodeAddress(ActivityAddress address, string token) {
Microsoft.Samples.PlanMyNight.Bing.VEGeocodingService.GeocodeResponse geocodeResponse = null;
// Make the geocode request using (var geocodeService = new Microsoft.Samples.PlanMyNight.Bing.VEGeocodingService.GeocodeServiceClient() { try { geocodeResponse = geocodeService.Geocode(geocodeRequest) ; geocodeService.Close() ; } catch { geocodeService.Abort() ; } } 1f (geocodeResponse != null && geocodeResponse.Results != null && geocodeResponse.Results.Length > 0) {
var location = geocodeResponse.Results[0].Locations [0];
return new BingCoordinate { Latitude = (float)location.Latitude, Longitude = (float) location.Longitude }; } return defauTt(B1ngCoord1Inate) ; } Parallel Programming