在Silverlight中透過WCF&LINQ使用SQL

針對Silverlight開發者常遇到binding SQL應用,提出循序漸進的範例,其中包含WCF與LING這兩種技巧,原文請參考Displaying SQL Database Data in a DataGrid using LINQ and WCF,本文步驟title依照原文,除了不同處會額外說明,步驟內容只提供操作方式的中文,需瞭解更詳細說明與操作意義者請參考原出處。
  1. Getting Started
    新增一Silverlight專案,命名為SqlData,為了後續使用WCF,我們需要Silverlight Project和Server Project,專案類型請選ASP.NET Web應用程式專案(ASP.NET Web Application Project)



  2. Examining the Two Projects
    VS2008會在名為SqlData的方案下為您新增2個project


    您的SQLDataTestPage.aspx將會自動以ScriptManager裝載未來的xaml以進行測試,如下圖。如果像piggy一樣已安裝Silverlight 3 Tool for VS2008的朋友,你的*.aspx會長的和*.html一樣,這邊不用擔心~只是描述的方式不同罷了,您還是可以改成以前Silverlight 2預設的裝載模式(使用ScriptManager)。可參考本狀況的詳細描述


  3. Linq To Sql
    對Server Project(SqlData.Web)按右鍵加入新項目,選擇「LINQ to SQL類別」


  4. 打開伺服器總管(Server Explorer)找到資料庫AdventureWorks    

    將Customers資料表直接拖曳到DataClasses1.dbml頁面




  5. Make the resulting LINQ class Serializable
    滑鼠左鍵在DataClasses1.dbml空白處按一下,接著至右側屬性視窗更改序列化模式(Serialization Mode),將無(None)改為單向(Unidirectional)


  6. Create the Web Service
    對SqlData.Web按右鍵加入新項目,選擇「有Silverlight功能的WCF服務」,此時專案終獲多2個新檔案Service1.svc以及Service1.svc.vb


    下預設的DoWork方法改成我們設計的新方法,新方法將利用TerritoryID取回該客戶的所有資料,新方法的完整代碼如下
        Function GetCustomersByTerritoryID(ByVal territoryId As Integer) As List(Of Customer)
            Dim db As New DataClasses1DataContext
            Dim matchingCustomers = From cust In db.Customer _
                                    Where cust.TerritoryID.Equals(territoryId) _
                                    Select cust
            Return matchingCustomers.ToList()
        End Function

  7. LINQ Syntax
    不瞭解何謂LINQ者請參照原文p11或其他更深入的書籍

  8. Watch Out for the Binding!(超重要)
    WCF在web.config預設binding是使用wsHttpBinding
    < services >
    < service behaviorConfiguration="SqlData.Web.Service1Behavior"
                    name="SqlData.Web.Service1" >
          < endpoint address="" binding="customBinding" bindingConfiguration="customBinding0" contract="SqlData.Web.Service1" />
          < endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
    < /service >
    < /services >

    但是Silverlight只支援basic binding (例如SOAP 1.1),,需要手動更改binging!
    < services >
    < service behaviorConfiguration="SqlData.Web.Service1Behavior"
                    name="SqlData.Web.Service1">
          < endpoint address="" binding="basicHttpBinding" contract="SqlData.Web.Service1" />
          < endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
    < /service >
    < /services >

    OK!我們的服務已經架設好勒!

  9. Creating the Silverlight Application
    對Silverlight Application(SqlData)的參考按右鍵,選擇「加入服務參考」


    加入服務參考視窗出現後,按下搜尋(Discover)並選擇「方案中的服務」,我們新建的服務將會被找到,服務中的GetCustomersByTerritoryID也可以一併察看。


    選擇Service1按下確定,之後就可以透過這個參考去存取服務。


  10. Creating the XAML
    接下來設計一個簡單的UI,包含2個row,第1個用來放使用者輸入的TerritoryID,第2個放查詢結果。首先配置容器Grid的layout,xaml碼如下

        < Grid x:Name="LayoutRoot" Background="White" ShowGridLines="True">
            < Grid.RowDefinitions>
                < RowDefinition Height="10" />
                < RowDefinition Height="50" />
                < RowDefinition Height="*" />
                < RowDefinition Height="10" />
            < /Grid.RowDefinitions>
            < Grid.ColumnDefinitions>
                < ColumnDefinition Width="10" />
                < ColumnDefinition Width="*" />
                < ColumnDefinition Width="10" />
            < /Grid.ColumnDefinitions>
        < /Grid>

    使用Expression Blend 3開啟xaml將會看到下圖成果,總共有3個row、2個column,邊邊都是為了版面故意規劃的row&column,主要是下圖2個大塊的row,如果用VS2008設計檢視看不到或看到的layout很怪的話,請用Blend 3來make sure



  11. Placing controls in the top row
    在第1個row準備放入3個控制項—Textblock、TextBox、Button,為了快速配置3個控制項於row1,我們採用stack panel,然後用border來框住這個範圍

    < Border BorderBrush="Black" BorderThickness="2" Grid.Row="1" Grid.Column="1"/>
    < StackPanel Grid.Row="1" Grid.Column="1" Orientation="Horizontal">
    < TextBlock Text="Last name to search for: " VerticalAlignment="Bottom" FontSize="18" Margin="15,0,0,0" />
        < TextBox x:Name="LastName" Width="250" Height="30" Margin="2,0,0,4" VerticalAlignment="Bottom"/>
        < Button x:Name="Search" Width="75" Height="30" Margin="20,0,0,4" Content="Search" VerticalAlignment="Bottom" Background="Blue" FontWeight="Bold" FontSize="14" />
    < /StackPanel>


    在第2個大塊的row放一個DataGrid

    < data:DataGrid x:Name="theDataGrid_" Margin="40,15" Grid.Column="1" Grid.Row="2" Width="700" Height="500" d:LayoutOverrides="GridBox"/>

    介面設計完成!

  12. Write the Event Handler for the Search Button
    我們希望UI中的Button被按下去之後會執行查詢的動作(搜尋和Text Box具有相同TerritoryID的顧客),所以要開始在*.xaml.vb撰寫程式碼

    Private Sub Page_Loaded(ByVal sender As Object, ByVal e As RoutedEventArgs)
            AddHandler Search.Click, AddressOf Search_Click
    End Sub

    'Write the Event Handler for the Search Button
    Private Sub Search_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
    Dim webService As ServiceReference1.Service1Client = New ServiceReference1.Service1Client()
       AddHandler webService.GetCustomersByTerritoryIDCompleted, AddressOf webService_GetCustomersByTerritoryIDCompleted
       '注意:從Silverlight呼叫服務只能用非同步(Asynchronously)的方式
        webService.GetCustomersByTerritoryIDAsync(TerritoryID.Text)
    End Sub

    Private Sub webService_GetCustomersByTerritoryIDCompleted(ByVal sender As Object, ByVal e As SqlData.ServiceReference1.GetCustomersByTerritoryIDCompletedEventArgs)
    theDataGrid.ItemsSource = e.Result
    End Sub

    當然是件處理常式撰寫完畢後,要記得指派給Button,所以請在其屬性加上Click="Search_Click"

  13. 測試
    build成功後,輸入3搜尋(TerritoryID是Integer型別),可即刻取得ID為3的顧客資料。


    ★參考網址
    原出處
    下載AdventureWork資料庫
    本文使用的AdventureWork資料庫(搭配SQL Server Express 2005)

沒有留言: