您的位置:首页 > 其它

稳扎稳打Silverlight(56) - 4.0通信之与 WCF Data Services 进行通信

2012-11-27 08:56 495 查看
http://tech.cncms.com/web/aspnet/3266.html

介绍

Silverlight 4.0 对 WCF Data Services 的支持:

* DataServiceCollection<T> - 继承自 ObservableCollection<T>,用于将 WCF Data Services 提供的数据绑定到 Silverlight 控件上,当数据发生变化时可提供通知

在线DEMO
http://www.cnblogs.com/webabcd/archive/2010/08/09/1795417.html
示例

演示 Silverlight 4.0 与 WCF Data Services 之间的通信

1、服务端

MyWCFDataService.svc.cs

代码

/*

 * WCF Data Services - 用于提供基于 OData 协议的数据服务

 * OData 协议 - 开放数据协议(Open Data Protocol),其基于 REST-ful 协议,参考:http://www.odata.org/

 */

using System;

using System.Collections.Generic;

using System.Data.Services;

using System.Data.Services.Common;

using System.Linq;

using System.ServiceModel.Web;

using System.Web;

namespace Silverlight40.Web.Service

{

    public class MyWCFDataService : DataService<Model.NorthwindEntities>

    {

        public static void InitializeService(DataServiceConfiguration config)

        {

            config.SetEntitySetAccessRule("*", EntitySetRights.All);

            // 指定对 Products, Categories, Orders 启用服务端分页,页大小为 3

            config.SetEntitySetPageSize("Products", 3);

            config.SetEntitySetPageSize("Categories", 3);

            config.SetEntitySetPageSize("Orders", 3);

            config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;

        }

    }

}


2、客户端

Demo.xaml

代码

<navigation:Page x:Class="Silverlight40.WCFDataServices.Demo"

           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"

           xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"

           xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"

           Title="Demo Page">

    <Grid x:Name="LayoutRoot">

        <StackPanel Orientation="Vertical" HorizontalAlignment="Left">

            <!--

                    用于演示通过 WCF Data Services 实现数据的增删改查

                -->

            <StackPanel Orientation="Horizontal">

                <Button Name="btnGetData" Content="获取数据" Margin="5" Click="btnGetData_Click" />

            </StackPanel>

            <TextBlock Text="产品类别列表:" Margin="5" />

            <sdk:DataGrid Name="gridCategory" Margin="5" Height="200" Width="400" AutoGenerateColumns="False" ItemsSource="{Binding}"

                       SelectionChanged="gridCategory_SelectionChanged">

                <sdk:DataGrid.Columns>

                    <sdk:DataGridTextColumn Header="类别ID" Binding="{Binding CategoryID}" IsReadOnly="True" />

                    <sdk:DataGridTextColumn Header="类别名称" Binding="{Binding CategoryName}" />

                </sdk:DataGrid.Columns>

            </sdk:DataGrid>

            <TextBlock Text="产品列表:" Margin="5" />

            <sdk:DataGrid Name="gridProduct" Margin="5" Height="200" Width="400" AutoGenerateColumns="False" ItemsSource="{Binding}" >

                <sdk:DataGrid.Columns>

                    <sdk:DataGridTextColumn Header="产品ID" Binding="{Binding ProductID}" IsReadOnly="True" />

                    <sdk:DataGridTextColumn Header="产品名称" Binding="{Binding ProductName}" />

                    <sdk:DataGridTextColumn Header="单价" Binding="{Binding UnitPrice}" IsReadOnly="True" />

                </sdk:DataGrid.Columns>

            </sdk:DataGrid>

            <Button Name="btnSave" Content="保存" Margin="5" Width="400" Click="btnSave_Click" />

 

            <!--

                    用于演示 WCF Data Services 的服务端分页

                -->

            <TextBlock Text="订单列表:" Margin="5,20,5,5" />

            <sdk:DataGrid Name="gridOrder" Margin="5" Height="200" Width="400" IsReadOnly="True" AutoGenerateColumns="False" ItemsSource="{Binding}" >

                <sdk:DataGrid.Columns>

                    <sdk:DataGridTextColumn Header="订单ID" Binding="{Binding OrderID}" />

                    <sdk:DataGridTextColumn Header="客户ID" Binding="{Binding CustomerID}" />

                </sdk:DataGrid.Columns>

            </sdk:DataGrid>

            <TextBlock Name="txtCurrentPageIndex" />

            <Button Name="btnPrev" Content="上一页" Margin="5" Width="400" />

            <Button Name="btnNext" Content="下一页" Margin="5" Width="400" />

        </StackPanel>

    </Grid>

</navigation:Page>


Demo.xaml.cs

代码

/*

 * 演示 Silverlight 4.0 与 WCF Data Services 之间的通信

 *

 * DataServiceCollection<T> - 继承自 ObservableCollection<T>。用于将 WCF Data Services 提供的数据绑定到 Silverlight 控件上,当数据发生变化时可提供通知

 *     LoadAsync(IQueryable<T>) - 从数据服务上异步加载 IQueryable<T> 数据到 DataServiceCollection<T> 中(在 LoadCompleted 触发之前不能再调用此方法)

 *     LoadAsync() - 当 DataServiceCollection<T> 表示为某实体的导航属性时,从数据服务上异步加载该数据(在 LoadCompleted 触发之前不能再调用此方法)

 *     LoadCompleted - 异步加载完成后所触发的事件

 *         LoadCompletedEventArgs - LoadCompleted 事件的事件参数

 *         LoadCompletedEventArgs.QueryOperationResponse - 获取数据服务对改查询操作的响应

 *             QueryOperationResponse.Error - 引发的异常

 *             QueryOperationResponse.Headers -  HTTP 的响应头

 *             QueryOperationResponse.Query - 对应的 DataServiceQuery(DataServiceQuery.RequestUri - 请求数据服务的 URI) 对象

 *             QueryOperationResponse.StatusCode - HTTP 的响应代码

 *     Continuation - 返回一个 DataServiceQueryContinuation<T> 对象,该对象封装了当前查询结果的下一页的 URI

 *         DataServiceQueryContinuation<T>.NextLinkUri - 当前查询结果的下一页的 URI

 *     LoadNextPartialSetAsync() - 加载下一页数据到 DataServiceCollection<T> 中

 *

 * Silverlight 通过 ObservableCollection<T> 与 ADO.NET Data Services 1.0 进行通信详见 http://www.cnblogs.com/webabcd/archive/2009/03/12/1409281.html 
 * WCF Data Services(ADO.NET Data Services 1.5)新特性详见 http://www.cnblogs.com/webabcd/archive/2010/06/11/1756071.html 
 */

using System;

using System.Collections.Generic;

using System.Linq;

using System.Net;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Documents;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Animation;

using System.Windows.Shapes;

using System.Windows.Navigation;

using Silverlight40.MyWCFDataServiceReference;

using System.Data.Services.Client;

namespace Silverlight40.WCFDataServices

{

    public partial class Demo : Page

    {

        private NorthwindEntities _context;

        private DataServiceCollection<Category> _categories;

        public Demo()

        {

            InitializeComponent();

        }

        protected override void OnNavigatedTo(NavigationEventArgs e)

        {

            // 指定数据服务地址

            _context = new NorthwindEntities(new Uri("Service/MyWCFDataService.svc", UriKind.Relative));

            _categories = new DataServiceCollection<Category>();

            _categories.LoadCompleted += new EventHandler<LoadCompletedEventArgs>(_categories_LoadCompleted);

            // 演示如何通过 WCF Data Services 做服务端分页

            ServerPagingDemo();

        }

        // 开始异步加载 Categories 数据

        private void btnGetData_Click(object sender, RoutedEventArgs e)

        {

            gridCategory.DataContext = null;

            gridProduct.DataContext = null;

            // 加载 Categories 表中的全部数据

            var query = from c in _context.Categories select c;

            _categories.LoadAsync(query);

            btnGetData.IsEnabled = false;

        }

        // 异步加载 Categories 数据完成

        void _categories_LoadCompleted(object sender, LoadCompletedEventArgs e)

        {

            if (e.Error == null)

            {

                if (_categories.Continuation != null)

                {

                    // 在数据服务中 Categories 被服务端分页了,所以需要不断调用 LoadNextPartialSetAsync() ,以便加载全部的 Categories 数据

                    _categories.LoadNextPartialSetAsync();

                }

                else

                {

                    gridCategory.DataContext = _categories;

                    gridCategory.SelectedIndex = 0;

                    btnGetData.IsEnabled = true;

                }

            }

            else

            {

                MessageBox.Show(e.Error.ToString());

                btnGetData.IsEnabled = true;

            }

        }

        // 开始异步加载指定 Category 下的 Products 数据

        private void gridCategory_SelectionChanged(object sender, SelectionChangedEventArgs e)

        {

            Category category = gridCategory.SelectedItem as Category;

            if (category != null)

            {

                if (category.Products.Count == 0)

                {

                    category.Products.LoadCompleted += new EventHandler<LoadCompletedEventArgs>(Products_LoadCompleted);

                    try

                    {

                        // 加载实体的导航属性数据

                        category.Products.LoadAsync();

                    }

                    catch (InvalidOperationException ex)

                    {

                        MessageBox.Show(ex.ToString());

                    }

                }

                else

                {

                    gridProduct.DataContext = category.Products;

                }

            }

        }

        // 异步加载 Products 数据完成

        void Products_LoadCompleted(object sender, LoadCompletedEventArgs e)

        {

            if (e.Error == null)

            {

                DataServiceCollection<Product> products = sender as DataServiceCollection<Product>;

                if (products.Continuation != null)

                {

                    try

                    {

                        products.LoadNextPartialSetAsync();

                    }

                    catch (InvalidOperationException ex)

                    {

                        MessageBox.Show(ex.ToString());

                    }

                }

                else

                {

                    gridProduct.DataContext = products;

                }

            }

            else

            {

                MessageBox.Show(e.Error.ToString());

            }

        }

        // 异步保存 Categories 中的被更新的数据(包括增删改),由于 Products 是 Category 的导航属性,所以相关的 Products 的数据的更新也会被保存

        private void btnSave_Click(object sender, RoutedEventArgs e)

        {

            try

            {

                /*

                 * NorthwindEntities - 继承自 DataServiceContext,在 VS 中引用服务后会自动生成这个对象

                 *     DataServiceContext.BeginSaveChanges() - 将有变化的数据提交至数据服务端进行更新

                 *     DataServiceContext.EndSaveChanges() - 获取 BeginSaveChanges() 操作的结果,返回一个 DataServiceResponse 类型的对象

                 */

                _context.BeginSaveChanges(SaveChangesOptions.Batch, OnChangesSaved, null);

            }

            catch (Exception ex)

            {

                MessageBox.Show(ex.ToString());

            }

        }

        // 数据被异步保存后

        private void OnChangesSaved(IAsyncResult result)

        {

            bool error = false;

            this.Dispatcher.BeginInvoke(() =>

            {

                try

                {

                    DataServiceResponse response = _context.EndSaveChanges(result);

                    foreach (ChangeOperationResponse changeResponse in response)

                    {

                        if (changeResponse.Error != null)

                            error = true;

                    }

                    if (!error)

                    {

                        MessageBox.Show("数据更新成功");

                    }

                    else

                    {

                        MessageBox.Show("数据更新失败");

                    }

                }

                catch (Exception ex)

                {

                    MessageBox.Show(ex.ToString());

                }

            });

        }

 

        private int _pageIndex = 0;

        private int _pageSize = 3;

        // 演示如何通过 WCF Data Services 做服务端分页

        private void ServerPagingDemo()

        {

            BindOrder();

            btnNext.Click += (s, args) =>

            {

                _pageIndex++;

                BindOrder();

            };

            btnPrev.Click += (s, args) =>

            {

                _pageIndex--;

                BindOrder();

            };

        }

        private void BindOrder()

        {

            txtCurrentPageIndex.Text = "当前页索引:" + _pageIndex.ToString();

            var query = from o in _context.Orders select o;

            query = query.Skip(_pageIndex * _pageSize).Take(_pageSize);

            DataServiceCollection<Order> orders = new DataServiceCollection<Order>();

            orders.LoadAsync(query);

            orders.LoadCompleted += (s, args) =>

            {

                gridOrder.DataContext = orders;

            };

        }

    }

}


OK

源码下载:http://files.cnblogs.com/webabcd/Silverlight.rar
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐