天天看點

穩紮穩打Silverlight(28) - 2.0通信之調用ADO.NET Data Services(資料服務)

<a href="http://webabcd.blog.51cto.com/1787395/342790" target="_blank">[索引頁]</a>

<a href="http://down.51cto.com/data/100302" target="_blank">[源碼下載下傳]</a>

穩紮穩打Silverlight(28) - 2.0通信之調用ADO.NET Data Services(資料服務)

介紹

Silverlight 2.0 調用 ADO.NET Data Services (資料服務)。本文以 Northwind 資料庫為示例資料庫,做一個添加、查詢、更新和删除的Demo 

    在 Silverlight 2.0 中調用資料服務隻能使用異步方式調用。另外,資料服務要與 Silverlight 宿主放在相同的域上

    System.Data.Services.Client.DataServiceContext - 資料服務上下文

    System.Data.Services.Client.DataServiceQuery - 以指定的 URI 文法查詢資料服務

    AddObject(), UpdateObject(), DeleteObject() - 本别用于添加, 更新, 删除實體

    BeginExecute()/EndExecute(), BeginExecuteBatch()/EndExecuteBatch - 用于執行某一個 DataServiceQuery 查詢或批量執行(将一組查詢一次性地送出到資料服務)

    BeginSaveChanges()/EndSaveChanges() - 用于送出對實體的修改(增,删,改)

    BeginLoadProperty()/EndLoadProperty() - 用于加載指定的屬性的值,加載導航屬性的時候需要用到它

    AddLink(), SetLink(), DeleteLink() - 分别為建立連接配接,Added狀态(一對多);建立連接配接,Added狀态(多對一);删除連接配接,Deleted狀态

線上DEMO

示例

1、資料服務

NorthwindDataService.svc

&lt;%@ ServiceHost Language="C#" Factory="System.Data.Services.DataServiceHostFactory, System.Data.Services, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" Service="Silverlight20.Web.DataService.NorthwindDataService" %&gt;

NorthwindDataService.svc.cs

using System; 

using System.Collections.Generic; 

using System.Data.Services; 

using System.Linq; 

using System.ServiceModel.Web; 

using System.Web; 

namespace Silverlight20.Web.DataService 

        public class NorthwindDataService : DataService&lt;NorthwindEntities&gt; 

        { 

                public static void InitializeService(IDataServiceConfiguration config) 

                { 

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

                } 

        } 

}

2、Silverlight 調用資料服務

DataService.xaml

&lt;UserControl x:Class="Silverlight20.Communication.DataService" 

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

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

        xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"&gt; 

        &lt;StackPanel HorizontalAlignment="Left" Margin="5"&gt; 

                &lt;TextBlock x:Name="lblMsg" Margin="10" Foreground="Red" /&gt; 

                &lt;StackPanel Orientation="Horizontal"&gt; 

                        &lt;TextBlock x:Name="lblCategoryName" Text="類别名稱" Margin="10" /&gt; 

                        &lt;TextBox x:Name="txtCategoryName" Width="100" Margin="10" /&gt; 

                        &lt;TextBlock x:Name="lblDescription" Text="類别備注" Margin="10" /&gt; 

                        &lt;TextBox x:Name="txtDescription" Width="100" Margin="10" /&gt; 

                        &lt;Button x:Name="btnAdd" Content="添加" Margin="10" Click="btnAdd_Click" /&gt; 

                &lt;/StackPanel&gt; 

                        &lt;Button x:Name="btnUpdate" Content="更新選中" Margin="10" Click="btnUpdate_Click" /&gt; 

                        &lt;Button x:Name="btnDelete" Content="删除選中" Margin="10" Click="btnDelete_Click"    /&gt; 

                &lt;data:DataGrid Name="dataGrid1" Margin="10" AutoGenerateColumns="False" ItemsSource="{Binding}" 

                        SelectionChanged="DataGrid_SelectionChanged"&gt; 

                        &lt;data:DataGrid.Columns&gt; 

                                &lt;data:DataGridTextColumn Header="類别ID" Binding="{Binding CategoryID}" /&gt; 

                                &lt;data:DataGridTextColumn Header="類别名稱" Binding="{Binding CategoryName}" /&gt; 

                                &lt;data:DataGridTextColumn Header="類别備注" Binding="{Binding Description}" /&gt; 

                        &lt;/data:DataGrid.Columns&gt; 

                &lt;/data:DataGrid&gt; 

                &lt;data:DataGrid Name="dataGrid2" Margin="10" AutoGenerateColumns="False" ItemsSource="{Binding}"&gt; 

                                &lt;data:DataGridTextColumn Header="産品ID" Binding="{Binding ProductID}" /&gt; 

                                &lt;data:DataGridTextColumn Header="産品名稱" Binding="{Binding ProductName}" /&gt; 

        &lt;/StackPanel&gt; 

&lt;/UserControl&gt;

DataService.xaml.cs

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.Data.Services.Client; 

using System.Collections.ObjectModel; 

using Silverlight20.NorthwindDataService; 

namespace Silverlight20.Communication 

        public partial class DataService : UserControl 

                // 配置服務位址,資料服務要與 Silverlight 宿主放在相同的域上 

                Uri uri = new Uri("DataService/NorthwindDataService.svc", UriKind.Relative); 

                NorthwindEntities ctx; 

                ObservableCollection&lt;Categories&gt; categories; 

                ObservableCollection&lt;Products&gt; products; 

                public DataService() 

                        InitializeComponent(); 

                        this.Loaded += new RoutedEventHandler(DataService_Loaded); 

                void DataService_Loaded(object sender, RoutedEventArgs e) 

                        // 執行個體化 DataServiceContext 

                        ctx = new NorthwindEntities(uri); 

                        // 初始化 Categories 集合,為了做 OneWay ,是以是 ObservableCollection&lt;Categories&gt; 類型 

                        categories = new ObservableCollection&lt;Categories&gt;(); 

                        // 初始化 Products 集合,為了做 OneWay ,是以是 ObservableCollection&lt;Products&gt; 類型 

                        products = new ObservableCollection&lt;Products&gt;(); 

                        BindCategory(); 

                private void BindCategory() 

                        DataServiceQuery&lt;Categories&gt; query = ctx.Categories; 

                        // IAsyncResult BeginExecute(AsyncCallback callback, object state) - 以異步方式送出請求 

                        //         AsyncCallback callback - 經典的 AsyncCallback 委托,指定回調方法 

                        //         object state - 傳遞給回調方法的自定義對象,此處必須是 DataServiceQuery&lt;T&gt; 類型 

                        query.BeginExecute(OnBindCategoryCompleted, query); 

                        // RequestUri - 請求服務的位址,因為資料服務釋出的是REST,是以也可以用自己構造 URI 的方式去調用資料服務,詳細的 URI 文法請參看 MSDN 

                        lblMsg.Text = "讀取類别資料中。。。" + query.RequestUri.ToString(); 

                void OnBindCategoryCompleted(IAsyncResult ar) 

                        try 

                        { 

                                var query = ar.AsyncState as DataServiceQuery&lt;Categories&gt;; 

                                // EndExecute(IAsyncResult ar) - 擷取異步查詢的結果 

                                var result = query.EndExecute(ar); 

                                foreach (var item in result) 

                                { 

                                        categories.Add(item); 

                                } 

                                this.Dispatcher.BeginInvoke(() =&gt; 

                                        dataGrid1.DataContext = categories; 

                                        lblMsg.Text = ""; 

                                }); 

                        } 

                        catch (DataServiceRequestException ex) 

                                lblMsg.Text = ex.ToString(); 

                private void btnAdd_Click(object sender, RoutedEventArgs e) 

                        Categories category = new Categories(); 

                        category.CategoryName = txtCategoryName.Text; 

                        category.Description = txtDescription.Text; 

                        ctx.AddToCategories(category); 

                        for (int i = 0; i &lt; 10; i++) 

                                var product = new Products() { ProductName = "測試用" + i.ToString() }; 

                                product.Categories = category; 

                                ctx.AddToProducts(product); 

                                // 多對一關系,使用 SetLink 建立連接配接,BeginSaveChanges() 的時候會一起發送到資料服務 

                                ctx.SetLink(product, "Categories", category); 

                        ctx.BeginSaveChanges(OnAddCompleted, category); 

                        lblMsg.Text = "新增資料中。。。"; 

                void OnAddCompleted(IAsyncResult ar) 

                                var x = ctx.EndSaveChanges(ar); 

                                categories.Add(ar.AsyncState as Categories); 

                private void DataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e) 

                        var category = e.AddedItems[0] as Categories; 

                        BindProduct(category.CategoryID); 

                private void BindProduct(int categoryId) 

                        // 可以使用 Lambda 表達式或查詢文法,然後将其轉換為 DataServiceQuery&lt;T&gt; 再使用 

                        DataServiceQuery&lt;Products&gt; query = 

                                (from p in ctx.Products where p.Categories.CategoryID == categoryId select p) as DataServiceQuery&lt;Products&gt;; 

                        lblMsg.Text = "讀取産品資料中。。。"; 

                        query.BeginExecute(OnBindProductCompleted, query); 

                void OnBindProductCompleted(IAsyncResult ar) 

                                var query = ar.AsyncState as DataServiceQuery&lt;Products&gt;; 

                                products.Clear(); 

                                        products.Add(item); 

                                        dataGrid2.DataContext = products; 

                private void btnDelete_Click(object sender, RoutedEventArgs e) 

                        if (dataGrid1.SelectedItem != null) 

                                try 

                                        Categories category = dataGrid1.SelectedItem as Categories; 

                                        DeleteCategory(category); 

                                        lblMsg.Text = "删除中。。。"; 

                                catch (DataServiceRequestException ex) 

                                        lblMsg.Text = ex.ToString(); 

                private void DeleteCategory(Categories category) 

                                // BeginLoadProperty(object entity, string propertyName, AsyncCallback callback, object state) - 開始加載指定屬性的值的異步操作 

                                //         object entity - 需要加載屬性的所屬實體    

                                //         string propertyName - 需要加載屬性的名稱 

                                //         AsyncCallback callback - 經典的 AsyncCallback 委托,指定回調方法 

                                //         object state - 傳遞給回調方法的自定義對象 

                                ctx.BeginLoadProperty(category, "Products", OnLoadPropertyCompleted, category); 

                void OnLoadPropertyCompleted(IAsyncResult ar) 

                        Categories category = ar.AsyncState as Categories; 

                                // EndLoadProperty(IAsyncResult ar) - 完成加載指定屬性的值的這個異步操作 

                                ctx.EndLoadProperty(ar); 

                                foreach (Products product in category.Products) 

                                        // 在指定的對象上删除指定的連接配接,BeginSaveChanges() 的時候會一起發送到資料服務 

                                        ctx.DeleteLink(category, "Products", product); 

                                ctx.DeleteObject(category); 

                                ctx.BeginSaveChanges(OnDeleteCategoryCompleted, null); 

                                categories.Remove(category); 

                void OnDeleteCategoryCompleted(IAsyncResult ar) 

                                ctx.EndSaveChanges(ar); 

                                lblMsg.Text = ""; 

                private void btnUpdate_Click(object sender, RoutedEventArgs e) 

                                        ctx.UpdateObject(category); 

                                        ctx.BeginSaveChanges(OnUpdateCategoryCompleted, category); 

                                        lblMsg.Text = "更新中。。。"; 

                void OnUpdateCategoryCompleted(IAsyncResult ar) 

OK

     本文轉自webabcd 51CTO部落格,原文連結:http://blog.51cto.com/webabcd/343917,如需轉載請自行聯系原作者