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

 [索引頁]
[源碼下載]


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


作者:webabcd


介紹
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
http://www.cnblogs.com/webabcd/archive/2008/10/09/1307486.html 


示例
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>

        
<StackPanel Orientation="Horizontal">
            
<Button x:Name="btnUpdate" Content="更新選中" Margin="10" Click="btnUpdate_Click" />
            
<Button x:Name="btnDelete" Content="刪除選中" Margin="10" Click="btnDelete_Click"  />
        
</StackPanel>

        
<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:DataGrid.Columns>
                
<data:DataGridTextColumn Header="產品ID" Binding="{Binding ProductID}" />
                
<data:DataGridTextColumn Header="產品名稱" Binding="{Binding ProductName}" />
            
</data:DataGrid.Columns>
        
</data:DataGrid>

    
</StackPanel>

</UserControl>

DataService.xaml.cs
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.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)
        
{
            
try
            
{
                var x 
= ctx.EndSaveChanges(ar);

                categories.Add(ar.AsyncState 
as Categories);

                
this.Dispatcher.BeginInvoke(() =>
                
{
                    lblMsg.Text 
= "";
                }
);
            }

            
catch (DataServiceRequestException ex)
            
{
                lblMsg.Text 
= ex.ToString();
            }

        }


        
private void DataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
        
{
            var category 
= e.AddedItems[0as 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)
        
{
            
try
            
{
                var query 
= ar.AsyncState as DataServiceQuery<Products>;

                var result 
= query.EndExecute(ar);
                products.Clear();
                
foreach (var item in result)
                
{
                    products.Add(item);
                }


                
this.Dispatcher.BeginInvoke(() =>
                
{
                    dataGrid2.DataContext 
= products;
                    lblMsg.Text 
= "";
                }
);
            }

            
catch (DataServiceRequestException ex)
            
{
                lblMsg.Text 
= ex.ToString();
            }

        }


        
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)
        
{
            
try
            
{
                
// BeginLoadProperty(object entity, string propertyName, AsyncCallback callback, object state) - 開始加載指定屬性的值的異步操作
                
//     object entity - 需要加載屬性的所屬實體 
                
//     string propertyName - 需要加載屬性的名稱
                
//     AsyncCallback callback - 經典的 AsyncCallback 委託,指定回調方法
                
//     object state - 傳遞給回調方法的自定義對象
                ctx.BeginLoadProperty(category, "Products", OnLoadPropertyCompleted, category);
            }

            
catch (DataServiceRequestException ex)
            
{
                lblMsg.Text 
= ex.ToString();
            }

        }


        
void OnLoadPropertyCompleted(IAsyncResult ar)
        
{
            Categories category 
= ar.AsyncState as Categories;

            
try
            
{
                
// 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);
            }

            
catch (DataServiceRequestException ex)
            
{
                lblMsg.Text 
= ex.ToString();
            }

        }


        
void OnDeleteCategoryCompleted(IAsyncResult ar)
        
{
            
try
            
{
                ctx.EndSaveChanges(ar);
                lblMsg.Text 
= "";

            }

            
catch (DataServiceRequestException ex)
            
{
                lblMsg.Text 
= ex.ToString();
            }

        }


        
private void btnUpdate_Click(object sender, RoutedEventArgs e)
        
{
            
if (dataGrid1.SelectedItem != null)
            
{
                
try
                
{
                    Categories category 
= dataGrid1.SelectedItem as Categories;

                    ctx.UpdateObject(category);
                    ctx.BeginSaveChanges(OnUpdateCategoryCompleted, category);
                    lblMsg.Text 
= "更新中。。。";
                }

                
catch (DataServiceRequestException ex)
                
{
                    lblMsg.Text 
= ex.ToString();
                }

            }

        }


        
void OnUpdateCategoryCompleted(IAsyncResult ar)
        
{
            
try
            
{
                ctx.EndSaveChanges(ar);
                lblMsg.Text 
= "";

            }

            
catch (DataServiceRequestException ex)
            
{
                lblMsg.Text 
= ex.ToString();
            }

        }

    }

}


OK
[源碼下載]
發佈了6 篇原創文章 · 獲贊 1 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章