Tutorial9 ADOnetDataEntities Cs
Tutorial9 ADOnetDataEntities Cs
Goals
The proximate goal of this exercise is to extract some data from a SQLServer Database, limited by a where clause and serve that data via a web service using WCF-SOAP. The data will then be consumed by a Silverlight application that will display it in a datagrid control. The more general goal is to show how these technologies work together to enable data retrieval relatively easily.
Figure 9-1. Web Project Visual Studio will create one solution with two projects:
The second project will house both the ADO.NET Entity model and the web service, while the first will hold the Silverlight DataGrid.
Figure 9-2. Choose Data Source and once the connection is made and the data structure retrieved, youll be asked to select which tables, views and stored proecedures youd like included in your model. For this exercise, to keep things very simple, well select just one table: Employee,
Figure 9-3. Choose Data Objects When you click Finish, your entity data model is generated. Spend a couple minutes looking at the result, it is quite cool. Note there may be a window hiding at the bottom of Visual Studio named Mapping Details. Be sure to open this and give it about half the screen. This is worth examining as well. Take your time, Ill wait here.
{ AdventureWorks_DataEntities ds = new AdventureWorks.DataEntities(); return ds.Employee.Where( emp => emp.SalariedFlag == true ).ToList(); } }
This code warrants a bit of examination. The first line of the GetEmployees method creates an instance of the DataEntity that we defined earlier. The second line asks the data entity instance for the Employee objects, but since there are a lot of them, it adds a where clause, using a lambda expression to narrow the return set and then calls ToList() on the result effectively casting the result set to a List<Employee>.
There are a number of ways to interpret this statement, depending on how precise you choose to be and how deeply you wish to dive into the corner cases (for an example of pushing on these issues, see this blog entry). One straightforward way to read this is let emp be all the employee objects whose SalariedFlag property evaluates to true.
Add a name for your grid (x:Name=dg) and remove the height and width of the surrounding UserControl. Here is the complete source for Page.xaml
<UserControl xmlns:data="clr-namespace:System.Windows.Controls;assembly = System.Windows.Controls.Data" x:Class="EntitiesSvcGrid.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <Grid x:Name="LayoutRoot" Background="White"> <data:DataGrid x:Name="dg" />
</Grid> </UserControl>
Figure 9-5. Add the Service Reference Click OK to add the service reference, and open Page.xaml.cs. I tend to set up event handlers in the Loaded event rather than in the constructor, though this may be a vestigial habit,
using System; using System.Windows; using System.Windows.Controls; namespace EntitiesSvcGrid { public partial class Page : UserControl { public Page() { InitializeComponent();
Our job at this point is to create an instance of the web service client and then use that client to call the GetEmployees method on the web service. Instantiating the client is straight-forward,
EmployeeWebService.EmployeeWebServiceClient ws = new EntitiesSvcGrid.EmployeeWebService.EmployeeWebServiceClient();
Because Silverlight applications run in the browser, however, we cannot make direct method calls (you must not block the browser) but rather must make asynchronous calls. In fact, Intellisense not only offers an async alternative, it does not even offer the synchronous method you created!
public partial class Page : UserControl { public Page() { InitializeComponent(); Loaded += new RoutedEventHandler( Page_Loaded ); } void Page_Loaded( object sender, RoutedEventArgs e ) { EmployeeWebService.EmployeeWebServiceClient ws = new EntitiesSvcGrid.EmployeeWebService.EmployeeWebServiceClient(); ws.GetEmployeesCompleted += new EventHandler<EntitiesSvcGrid.EmployeeWebService. GetEmployeesCompletedEventArgs>( ws_GetEmployeesCompleted ); ws.GetEmployeesAsync(); } void ws_GetEmployeesCompleted( object sender, EntitiesSvcGrid.EmployeeWebService.GetEmployeesCompletedEventArgs e ) { dg.ItemsSource = e.Result; } } }
The work of the event handler is to bind the Result (obtained through the GetEmployeeCompletedEventArgs parameter) which is of type observableCollection<Employee>, to the ItemSource property of the data grid.
Figure 9-8. DataGrid While the appearance is a bit Spartan (weve taken no steps to limit or name the columns or to improve the UI with styles, much less templates) all the core functionality is intact, including sorting, as weve done with the HireDate column.
[1] Fuss, verb: to hack, debug or twiddle code. [2] You are of course free to name your projects and objects anything you like, but choosing the names used here makes it easier to follow along. [3] This expression was used in my home, when I was growing up, to describe a series of predictable but discrete events: not unlike the progression of data from the database, to the web service to the Silverlight datagrid. It refers to the famous turn of the century Chicago Cubs double play combination of Joe Tinker at Short, Johnny Evers at second and Frank Chance at first base which was memorialized in a poem by Franklin Pierce Adams, who once said "I find that a great part of the information I have was acquired by looking up something and finding something else on the way." The poem was first published in the New York Evening Mail, 45 years (to the day) prior to my birth and can be found here.