<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
<%@ 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" %>
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<NorthwindEntities>
{
public static void InitializeService(IDataServiceConfiguration config)
{
config.SetEntitySetAccessRule("*", EntitySetRights.All);
}
}
}
2、Silverlight 調用資料服務
DataService.xaml
<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">
<StackPanel HorizontalAlignment="Left" Margin="5">
<TextBlock x:Name="lblMsg" Margin="10" Foreground="Red" />
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="lblCategoryName" Text="類别名稱" Margin="10" />
<TextBox x:Name="txtCategoryName" Width="100" Margin="10" />
<TextBlock x:Name="lblDescription" Text="類别備注" Margin="10" />
<TextBox x:Name="txtDescription" Width="100" Margin="10" />
<Button x:Name="btnAdd" Content="添加" Margin="10" Click="btnAdd_Click" />
</StackPanel>
<Button x:Name="btnUpdate" Content="更新選中" Margin="10" Click="btnUpdate_Click" />
<Button x:Name="btnDelete" Content="删除選中" Margin="10" Click="btnDelete_Click" />
<data:DataGrid Name="dataGrid1" Margin="10" AutoGenerateColumns="False" ItemsSource="{Binding}"
SelectionChanged="DataGrid_SelectionChanged">
<data:DataGrid.Columns>
<data:DataGridTextColumn Header="類别ID" Binding="{Binding CategoryID}" />
<data:DataGridTextColumn Header="類别名稱" Binding="{Binding CategoryName}" />
<data:DataGridTextColumn Header="類别備注" Binding="{Binding Description}" />
</data:DataGrid.Columns>
</data:DataGrid>
<data:DataGrid Name="dataGrid2" Margin="10" AutoGenerateColumns="False" ItemsSource="{Binding}">
<data:DataGridTextColumn Header="産品ID" Binding="{Binding ProductID}" />
<data:DataGridTextColumn Header="産品名稱" Binding="{Binding ProductName}" />
</StackPanel>
</UserControl>
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<Categories> categories;
ObservableCollection<Products> 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<Categories> 類型
categories = new ObservableCollection<Categories>();
// 初始化 Products 集合,為了做 OneWay ,是以是 ObservableCollection<Products> 類型
products = new ObservableCollection<Products>();
BindCategory();
private void BindCategory()
DataServiceQuery<Categories> query = ctx.Categories;
// IAsyncResult BeginExecute(AsyncCallback callback, object state) - 以異步方式送出請求
// AsyncCallback callback - 經典的 AsyncCallback 委托,指定回調方法
// object state - 傳遞給回調方法的自定義對象,此處必須是 DataServiceQuery<T> 類型
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<Categories>;
// EndExecute(IAsyncResult ar) - 擷取異步查詢的結果
var result = query.EndExecute(ar);
foreach (var item in result)
{
categories.Add(item);
}
this.Dispatcher.BeginInvoke(() =>
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 < 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<T> 再使用
DataServiceQuery<Products> query =
(from p in ctx.Products where p.Categories.CategoryID == categoryId select p) as DataServiceQuery<Products>;
lblMsg.Text = "讀取産品資料中。。。";
query.BeginExecute(OnBindProductCompleted, query);
void OnBindProductCompleted(IAsyncResult ar)
var query = ar.AsyncState as DataServiceQuery<Products>;
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,如需轉載請自行聯系原作者