Msdn解释:
简而言之:如果使用WCF数据服务,就可以通过Rest的方式来访问和更改数据。
实战:
1:新建Asp.net 空Web应用程序:
2:因为WCF数据服务需要ado.net 实体,所以添加一个实体,命名为Northwind
3:添加了数据实体后,需要添加一个WCF数据服务
NorthwindWcfDataService.cs 代码如下:
- namespaceNorthwindDataServiceDemo
- {
- publicclassNorthwindWcfDataService: DataService</* TODO: 在此放置数据源类名*/>
- {
- // 仅调用此方法一次以初始化涉及服务范围的策略。
- publicstaticvoidInitializeService(DataServiceConfigurationconfig)
- {
- // TODO: 设置规则以指明哪些实体集和服务操作是可见的、可更新的,等等。
- // 示例:
- // config.SetEntitySetAccessRule("MyEntityset", EntitySetRights.AllRead);
- // config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All);
- config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
- }
- }
- }
- publicclassNorthwindWcfDataService: DataService</* TODO: 在此放置数据源类名*/>
在此放置数据源类名,在这里作为数据源的是Northwind.edmx 生成的NorthwindEntities。
将代码修改为:
publicclassNorthwindWcfDataService: DataService<NorthwindEntities>
因为需要设置规则来指明哪些实体集和服务操作是可见的、可更新的,等等。
所以将
- // 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: 设置规则以指明哪些实体集和服务操作是可见的、可更新的,等等。
- // 示例:
- // config.SetEntitySetAccessRule("MyEntityset", EntitySetRights.AllRead);
- // config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All);
- config.SetEntitySetAccessRule("*", EntitySetRights.All);
- config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
- config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
- }
- }
- }
4:所有一切都操作完毕后,可以在浏览器中查看。
好了,现在数据服务已经实现了,剩下的就是使用客户端来调用了。
创建控制台程序来调用WCF数据服务
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数据服务,所以客户端可以使用linq的方式来查询数据,从本质的角度来分析的话,不同的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数据服务。
1:创建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线程上执行的,所以会阻塞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
【编辑推荐】