實例理解WCF數(shù)據(jù)服務
Msdn解釋:
簡而言之:如果使用WCF數(shù)據(jù)服務,就可以通過Rest的方式來訪問和更改數(shù)據(jù)。
實戰(zhàn):
1:新建Asp.net 空Web應用程序:
2:因為WCF數(shù)據(jù)服務需要ado.net 實體,所以添加一個實體,命名為Northwind
3:添加了數(shù)據(jù)實體后,需要添加一個WCF數(shù)據(jù)服務
NorthwindWcfDataService.cs 代碼如下:
- namespaceNorthwindDataServiceDemo
- {
- publicclassNorthwindWcfDataService: DataService</* TODO: 在此放置數(shù)據(jù)源類名*/>
- {
- // 僅調用此方法一次以初始化涉及服務范圍的策略。
- publicstaticvoidInitializeService(DataServiceConfigurationconfig)
- {
- // TODO: 設置規(guī)則以指明哪些實體集和服務操作是可見的、可更新的,等等。
- // 示例:
- // config.SetEntitySetAccessRule("MyEntityset", EntitySetRights.AllRead);
- // config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All);
- config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
- }
- }
- }
- publicclassNorthwindWcfDataService: DataService</* TODO: 在此放置數(shù)據(jù)源類名*/>
在此放置數(shù)據(jù)源類名,在這里作為數(shù)據(jù)源的是Northwind.edmx 生成的NorthwindEntities。
將代碼修改為:
publicclassNorthwindWcfDataService: DataService<NorthwindEntities>
因為需要設置規(guī)則來指明哪些實體集和服務操作是可見的、可更新的,等等。
所以將
- // config.SetEntitySetAccessRule("MyEntityset", EntitySetRights.AllRead);
- // config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All);
修改為:
- config.SetEntitySetAccessRule("*", EntitySetRights.All);
- config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
完整的代碼如下:
- namespaceNorthwindDataServiceDemo
- {
- publicclassNorthwindWcfDataService: DataService<NorthwindEntities>
- {
- // 僅調用此方法一次以初始化涉及服務范圍的策略。
- publicstaticvoidInitializeService(DataServiceConfigurationconfig)
- {
- // TODO: 設置規(guī)則以指明哪些實體集和服務操作是可見的、可更新的,等等。
- // 示例:
- // config.SetEntitySetAccessRule("MyEntityset", EntitySetRights.AllRead);
- // config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All);
- config.SetEntitySetAccessRule("*", EntitySetRights.All);
- config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
- config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
- }
- }
- }
4:所有一切都操作完畢后,可以在瀏覽器中查看。
好了,現(xiàn)在數(shù)據(jù)服務已經實現(xiàn)了,剩下的就是使用客戶端來調用了。
創(chuàng)建控制臺程序來調用WCF數(shù)據(jù)服務
1:添加控制臺應用程序:
2:添加服務引用:
3:修改Program.cs 代碼如下:
- namespaceNorthwindConsoleApp
- {
- classProgram
- {
- staticvoidMain(string[] args)
- {
- UriserviceRootUri = newUri("http://localhost:34098/NorthwindWcfDataService.svc/");
- NorthwindService.NorthwindEntitiesnorthwindContext =
- newNorthwindService.NorthwindEntities(serviceRootUri);
- varproducts = northwindContext.Products.ToList();
- foreach(varproduct inproducts)
- {
- Console.WriteLine("{0},{1}", product.ProductID, product.ProductName);
- }
- Console.ReadLine();
- }
- }
- }
這段代碼主要是查詢Products,
因為使用了WCF數(shù)據(jù)服務,所以客戶端可以使用linq的方式來查詢數(shù)據(jù),從本質的角度來分析的話,不同的Linq查詢在后臺都會變成不同http請求地址,具體的請求地址可以查看RequestUri屬性。
結果如下:
在這里可以看到Order_Details 的count 為0,
如果想要在查詢Products的時候,同時查詢所有的Order_Details 那么可以將代碼修改如下:
varproducts = northwindContext.Products.ToList();
改為
varproducts = northwindContext.Products.Expand("Order_Details").ToList();
完整的代碼如下:
- staticvoidMain(string[] args)
- {
- UriserviceRootUri = newUri("http://localhost:34098/NorthwindWcfDataService.svc/");
- NorthwindService.NorthwindEntitiesnorthwindContext =
- newNorthwindService.NorthwindEntities(serviceRootUri);
- varproducts = northwindContext.Products.Expand("Order_Details").ToList();
- foreach(varproduct inproducts)
- {
- Console.WriteLine("id:{0},Name:{1},Orders:{2}",
- product.ProductID,
- product.ProductName,
- product.Order_Details.Count);
- }
- Console.ReadLine();
- }
3:使用Silverlight來調用WCF數(shù)據(jù)服務。
1:創(chuàng)建Silverlight應用程序
2:MainPage.xaml 代碼如下:
- <UserControlxmlns:sdkUserControlxmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" x:Class="NorthwindSilverlightApp.MainPage"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- mc:Ignorable="d"
- dd:DesignHeight="300"d:DesignWidth="400"> xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- mc:Ignorable="d"
- dd:DesignHeight="300"d:DesignWidth="400">
- <Gridx:NameGridx:Name="LayoutRoot"Background="White">
- <Grid.RowDefinitions>
- <RowDefinitionHeightRowDefinitionHeight="Auto" />
- <RowDefinitionHeightRowDefinitionHeight="*" />
- </Grid.RowDefinitions>
- <StackPanelGrid.RowStackPanelGrid.Row="0"HorizontalAlignment="Left" >
- <ButtonContentButtonContent="First"Click="First_Click" />
- </StackPanel>
- <sdk:DataGridGrid.Rowsdk:DataGridGrid.Row="1"x:Name="dataGrid1" />
- </Grid>
- </UserControl>
同理也需要添加服務引用:
3:MainPage.xaml.cs 代碼如下:
- namespaceNorthwindSilverlightApp
- {
- publicpartialclassMainPage: UserControl
- {
- publicMainPage()
- {
- InitializeComponent();
- }
- privatevoidFirst_Click(objectsender, RoutedEventArgse)
- {
- UriserviceRootUri = newUri("http://localhost:34098/NorthwindWcfDataService.svc/");
- NorthwindService.NorthwindEntitiesnorthwindContext =
- newNorthwindService.NorthwindEntities(serviceRootUri);
- try
- {
- varproducts = northwindContext.Products.ToList();
- dataGrid1.ItemsSource = products;
- }
- catch(Exceptionex)
- {
- MessageBox.Show(ex.Message);
- }
- }
- }
- }
4:運行,結果如下:
這是因為Silverlight 只支持異步操作,而
varproducts = northwindContext.Products.ToList();
使用的是同步操作
修改First_Click 代碼如下:
- privatevoidFirst_Click(objectsender, RoutedEventArgse)
- {
- UriserviceRootUri = newUri("http://localhost:34098/NorthwindWcfDataService.svc/");
- NorthwindService.NorthwindEntitiesnorthwindContext =
- newNorthwindService.NorthwindEntities(serviceRootUri);
- varproductsQuery = northwindContext.Products;
- northwindContext.BeginExecute<Product>(productsQuery.RequestUri,
- (ar) =>
- {
- varproducts = northwindContext.EndExecute<Product>(ar).ToList();
- dataGrid1.ItemsSource = products;
- },
- null);
- }
再次運行:
Silverlight 的異步
修改MainPage.xaml 代碼
- <StackPanelGrid.RowStackPanelGrid.Row="0"HorizontalAlignment="Left"Orientation="Horizontal" >
- <ButtonContentButtonContent="First"Click="First_Click" />
- <ButtonContentButtonContent="Second"Click="Second_Click" />
- </StackPanel>
之所以我在First_Click 中使用匿名委托是有原因的,因為如果你嘗試寫下面的代碼會阻塞瀏覽器。
- privatevoidSecond_Click(objectsender, RoutedEventArgse)
- {
- NorthwindService.NorthwindEntitiesnorthwindContext =
- newNorthwindService.NorthwindEntities(serviceRootUri);
- varproductsQuery = northwindContext.Products;
- IAsyncResultar = northwindContext.BeginExecute<Product>
- (productsQuery.RequestUri, null, null);
- ar.AsyncWaitHandle.WaitOne();
- varproducts = northwindContext.EndExecute<Product>(ar).ToList();
- dataGrid1.ItemsSource = products;
- }
這個問題的原因是ar.AsyncWaitHandle是在UI線程上執(zhí)行的,所以會阻塞UI線程。
解決這個問題的方式也比較簡單,使用ThreadPool或者是Task:
修改代碼如下,使用ThreadPool
- privatevoidSecond_Click(objectsender, RoutedEventArgse)
- {
- NorthwindService.NorthwindEntitiesnorthwindContext =
- newNorthwindService.NorthwindEntities(serviceRootUri);
- varproductsQuery = northwindContext.Products;
- ThreadPool.QueueUserWorkItem((obj) =>
- {
- IAsyncResultar = northwindContext.BeginExecute<Product>
- (productsQuery.RequestUri, null, null);
- ar.AsyncWaitHandle.WaitOne();
- varproducts = northwindContext.EndExecute<Product>(ar).ToList();
- dataGrid1.ItemsSource = products;
- });
- }
運行:
原因如下:
最后完整的代碼如下:
- privatevoidSecond_Click(objectsender, RoutedEventArgse)
- {
- NorthwindService.NorthwindEntitiesnorthwindContext =
- newNorthwindService.NorthwindEntities(serviceRootUri);
- varproductsQuery = northwindContext.Products;
- ThreadPool.QueueUserWorkItem((obj) =>
- {
- IAsyncResultar = northwindContext.BeginExecute<Product>
- (productsQuery.RequestUri, null, null);
- ar.AsyncWaitHandle.WaitOne();
- varproducts = northwindContext.EndExecute<Product>(ar).ToList();
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- dataGrid1.ItemsSource = products;
- });
- });
- }
作者:LoveJenny
出處:http://www.cnblogs.com/LoveJenny/
原文鏈接:http://www.cnblogs.com/LoveJenny/archive/2012/02/13/2350020.html
【編輯推薦】