程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> RIA服務與關系型數據

RIA服務與關系型數據

編輯:關於.NET

正如我們都有原罪,當你看一些技術演示的時候,大多數例子演示的都是單表的解決方案。你還能記得你上次開發單表系統是什麼時候嗎?

在RIA服務的演示中,大多數也都是單表的例子。那麼如何才能通過RIA檢索關系型(主/從結構)數據呢?我使用VS2010、Silverlight 4和WCF RIA 服務預覽版來演示下面的例子。我還使用了Chinook(直升機)示例數據庫,這是我最喜歡使用的簡單關系型數據示例之一。

創建附帶RIA服務的項目

這很容易,你只要創建一個新的Silverlight項目,並確保選中了“啟用.NET RIA服務”(沒錯,在對話框中它不叫WCF)。程序可以通過點擊一個簡單的按鈕來檢索藝術家及其相關專輯。這些是初始的XAML:

1: <Grid x:Name="LayoutRoot" Background="White">
2:     <StackPanel Width="400">
3:         <Button Content="Get Artist Information" x:Name="GetArtistButton" Click="GetArtistButton_Click" />
4:         <StackPanel Orientation="Horizontal">
5:             <StackPanel x:Name="ArtistsContext">
6:                 <StackPanel Orientation="Horizontal">
7:                     <TextBlock Text="Artists: " />
8:                     <TextBlock Text="{Binding ElementName=ListOfArtists, Path=Items.Count}" />
9:                 </StackPanel>
10:                 <ListBox x:Name="ListOfArtists" Width="200" Height="300" DisplayMemberPath="Name" ItemsSource="{Binding}"/>
11:             </StackPanel>
12:             <StackPanel x:Name="AlbumsContext">
13:                 <StackPanel Orientation="Horizontal">
14:                     <TextBlock Text="Albums: " />
15:                     <TextBlock Text="{Binding ElementName=ListOfAlbums, Path=Items.Count}" />
16:                 </StackPanel>
17:                 <ListBox x:Name="ListOfAlbums" DisplayMemberPath="Title" ItemsSource="{Binding}" Width="200" Height="300"/>
18:             </StackPanel>
19:         </StackPanel>
20:     </StackPanel>
21: </Grid>

現在我們要在服務器端創建相關模型和被調用的域服務。我用實體框架(Entity Framework,需.NET 4)創建出來的模型看起來像這樣:

現在我要為模型創建域服務類了(記住在創建完成模型以後編譯一下解決方案,這樣你就可以在工具箱中找到它們了)。當我們創建域服務類的時候要確保選中了“為元數據生成相關聯的類”的多選框,這樣點擊完成後就會為我們創建一些存根服務。

使用域服務功能

我們已經有GetArtists和GetAlbums功能可以使用了。作為例子,我們可以通過默認函數將點擊按鈕關聯到獲取藝術家列表上:

1: ChinookContext ctx = new ChinookContext();
2:
3: private void GetArtistButton_Click(object sender, RoutedEventArgs e)
4: {
5:     ArtistsContext.DataContext = ctx.Artists;
6:     ctx.Load(ctx.GetArtistsQuery());
7: }

但是當用戶點擊一個藝術家的時候,我們希望顯示那個藝術家的專輯,而不是其他人的。因此,我們需要修改域服務,添加以下函數:

1: public IQueryable<Album> GetAlbumsForArtist(int ArtistId)
2: {
3:     return this.ObjectContext.Albums.Where(a => a.ArtistId == ArtistId);
4: }

現在我們可以在用戶點擊相關藝術家的時候使用這個函數來顯示專輯信息:

1: private void ListOfArtists_SelectionChanged(object sender, SelectionChangedEventArgs e)
2: {
3:     ListBox theList = sender as ListBox;
4:     Artist a = theList.SelectedItem as Artist;
5:     ctx.Albums.Clear();
6:     AlbumsContext.DataContext = ctx.Albums;
7:     ctx.Load(ctx.GetAlbumsForArtistQuery(a.ArtistId));
8: }

太棒了。

然而,處理這個特定的數據集的細節部分似乎沒有必要。畢竟,如果我們知道我們正在操作一個明確的主從關系視圖,為什麼不僅僅包括子數據和初始化請求呢?(而且我們的數據集相對來說並不是很龐大)。

修改元數據類

還記得生成的元數據類嗎?現在回過頭去。你將看到藝術家元數據的定義包括以下內容:

1: public EntityCollection<Album> Albums;

注意到它有一個專輯集合屬性。太棒了,我們只需要修改一些XAML綁定,並獲得選中的專輯屬性就行了嗎?不,還不行。如果僅僅這麼做,你將無法獲得任何數據。為什麼?因為我們沒有通知RIA服務去進行必要的額外查詢以獲得數據。在專輯集合頂部添加[include]:

1: [Include]
2: public EntityCollection<Album> Albums;

這正是我們需要的。現在我們就能添加一個函數到域服務類以獲取數據了:

1: public IQueryable<Artist> GetArtistsWithAlbums()
2: {
3:     return this.ObjectContext.Artists.Include("Albums");
4: }

現在我們需要做一些清理。現在我們要改變按鈕點擊代碼以獲取GetArtistsWithAlbums查詢,來替換掉先前的那個。

刪除不必要的代碼,並使用綁定

現在我們可以為藝術家ListBox刪除SelectionChanged事件處理器了,同時添加一些綁定命令到XAML,看起來像這樣:

1: <Grid x:Name="LayoutRoot" Background="White">
2:     <StackPanel Width="400">
3:         <Button Content="Get Artist Information" x:Name="GetArtistButton" Click="GetArtistButton_Click" />
4:         <StackPanel Orientation="Horizontal">
5:             <StackPanel x:Name="ArtistsContext">
6:                 <StackPanel Orientation="Horizontal">
7:                     <TextBlock Text="Artists: " />
8:                     <TextBlock Text="{Binding ElementName=ListOfArtists, Path=Items.Count}" />
9:                 </StackPanel>
10:                 <ListBox x:Name="ListOfArtists" Width="200" Height="300" DisplayMemberPath="Name" ItemsSource="{Binding}"/>
11:             </StackPanel>
12:             <StackPanel x:Name="AlbumsContext" DataContext="{Binding ElementName=ListOfArtists, Path=SelectedItem}" >
13:                 <StackPanel Orientation="Horizontal">
14:                     <TextBlock Text="Albums: " />
15:                     <TextBlock Text="{Binding ElementName=ListOfAlbums, Path=Items.Count}" />
16:                 </StackPanel>
17:                 <ListBox x:Name="ListOfAlbums" DisplayMemberPath="Title" ItemsSource="{Binding Albums}" Width="200" Height="300"/>
18:             </StackPanel>
19:         </StackPanel>
20:     </StackPanel>
21: </Grid>

注意專輯ListBox的DataContent現在是如何使用綁定來關聯到藝術家ListBox的SelectedItem上的。隨後的專輯的ListBox有一個{Binding Albums}命令。這是因為我們的藝術家查詢現在包括了關聯的專輯數據,我們只要引用屬性就行了。

請謹慎使用

雖然這個例子向我們展示了在域服務查詢結果中獲得包含結果(included results)是多麼地容易,但是使用的時候請一定要小心。假如你有一個1000個客戶的客戶數據庫,並且你希望查詢所有的訂單的話,使用這種特定類型未必是明智的做法。應該有選擇性地使用它。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved