開啟銀光的電燈開關LightSwitch(2) --資料庫開發者?程式開發者?傻傻分不清楚

  • 4927
  • 0
  • 2011-04-18

開啟銀光的電燈開關LightSwitch(2) --資料庫開發者?程式開發者?傻傻分不清楚

 

Dotblogs 的標籤:

長期以來,程式開發人員與資料庫開發人員就存在著本質上很大的差異。這從筆者之前輔導一些企業執行BI專案時就會發現。像是我就發現很多公司的資料庫管理員(事實上是程式開發人員兼任的…)是根本不會使用像是Join之類的語法,各位一定會認為哪有可能?不過我們認為資料庫人員都該會的語法,可是它們不但不會,反而會利用更厲害的(??)Cursor語法…。還有在資料倒檔時,我們很習慣的就會開啟SSIS,但是程式開發人員比較習慣自己寫程式轉檔。至於面對不同商業分析的需求,我們可以自己下SQL語法,或者是透過OLAP以及Reporting Services來進行分析,但是程式開發人員就會開始找適合的資料視覺化元件,打算開始來寫報表了。

 

 

這讓我想起來多年前筆者參加微軟MVP大會時,那時它們首次公布了LINQ to SQL的功能,難怪那些程式設計人員會那麼高興了,因為他解決了很多程式開發人員不會寫SQL查詢語法的問題。但是老實說,不管Entity Model功能再強大,習慣於自己下查詢的資料庫分析者還是總覺得絆手絆腳。所以LightSwitch已推出Beta2的現在,仔細想想,還是有點定位上的模糊。原先看起來的概念應該是讓懂得資料庫結構的人,在不用學很難的技術下,就可以自己開發商業應用程式;但是老實說,目前LightSwitch所支援的資料庫或者是RIA WCF Services,都對於資料庫的使用者太陌生了,光是轉換思考的模式就要花一段時間(我一直很難跟其他資料庫人員解釋為什麼"不可以"自己下一段語法取資料,而非要有事前定義的結構才有可能被程式存取)。因此,如果說LightSwitch造福的應該還是專業程式開發人員,那麼要程式開發人員乖乖地套用這些範本,恐怕也低估了程式開發者的創新性格。雖然定位上有點模糊,但是無庸置疑的LightSwitch仍然是筆者認為非常具有劃時代意義的產品,他解決了像我這樣董資料庫但是不會寫太難程式的人的痛苦,但是要付出的代價,就是要在資料結構上面做一些讓步以及新技術的學習,像是放棄使用預存程序(呵,除非你很厲害可以透過RIA WCF Services存取,筆者試了很久,RIA WCF Services對我來說還是一道難以突破的高牆),還有就是開始要乖乖地開始學習Entity Model(不過筆者就是習慣隨時可以下查詢、而且就是常用一些無法事前確定的資料結構,這些技術問題我已經有了初步的突破,之後會再整理與各位分享)。

 

以下筆者會開始以網路書店做為案例,來逐一展示LightSwitch的強大功能。一開始先只設計了一個資料表,就是書籍的主檔,包括了書籍的一些相關資訊,其中只有兩點要注意,LightSwitch預設的主索引鍵是利用Guid來實作,因此我們在資料庫上是利用uniqueidentifier來作主索引鍵,如果你沒設總索引鍵,那麼這個資料表就只能夠唯讀,而不行新增刪除了。

USE [LS_Sample]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[BookList](
	[BK_ID] [uniqueidentifier] NOT NULL,
	[BK_SEQ] [varchar](10) NULL,
	[ISBN] [varchar](20) NULL,
	[BK_NAME] [nvarchar](200) NULL,
	[PUBLISH] [nvarchar](50) NULL,
	[BK_URL] [varchar](200) NULL,
	[IMG] [varbinary](max) NULL,
	[BK_DESC] [nvarchar](500) NULL,
 CONSTRAINT [PK_BookList] PRIMARY KEY CLUSTERED 
(
	[BK_ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

image

此外,我有個欄位是用來存書籍的圖片,請各位將資料型別設定為varbinary(max)請不要再使用Image這個資料型別囉,因為在下一版SQL Server就不再支援了。至於如何把圖檔放入資料庫,在LightSwitch的世界中只是pieces of cake,但是如果您仍無法忘情資料庫,那也可以利用以下語法來寫入資料庫。

UPDATE dbo.BookList
SET IMG =(
SELECT * FROM OPENROWSET(
BULK 'C:\Book1.jpg',SINGLE_BLOB)AS A)
WHERE BK_ID='6863A681-B30F-419C-9A75-266F0D8BEAD2'

 

使用LightSwitch的第一步是先安裝Beta2,請注意如果有裝Beta1,必須先自行移除才可以安裝Beta2,而且您也必須先安裝Visual Studio 2010 SP1。

image

 

在之前的文章中,已經有介紹過LightSwitch Beta1的書籍主檔的頁面設計步驟,在此就不再贅述,不過我在這邊先拿Beta2完成的頁面來跟之前的結果做個比較:

image

 

Beta 2在畫面的美觀程度以及在控制項的版面控制能力是更強了,而且很多功能更符合Office Ribbon的設計概念。各位可以發現在畫面右方的現有書籍清單是可以支援新增刪除修改的,而畫面左邊的區塊,則是新增書籍的輸入介面。不過我們可以看到,畫面上是只有輸入資料的方框,但是缺少了欄位說明等資訊,因此我們可以回到原先的開發環境,在針對每個欄位做進一步的屬性設定。

image

image

 

目前LightSwitch的欄位屬性視窗如左圖所示,其中Display Name是呈現在畫面上的欄位說明,而在Description中輸入的內容則會以Tooltips的方式(滑鼠放在上方呈現說明)呈現。其中控制欄位說明位置的是要利用Label Position屬性,預設設成了None,所以才沒有出現,我們把它全部改成在左方,只有書籍圖示保持None,以及書籍內容描述設定成上方,

 

此外,在「Sizing」區域中,可以設定所有控制項的大小以及對齊模式,所以各位可以自行做調整。在此我是把所有控制像改成長度為150像素,除了書籍URL以及書籍內容描述都還是保持stretch,至於書籍描述,我們還可以把行數(Lines)開的稍為大些,以容納足夠的字數。

 

 

 

 

 

 

 

 

 

 

 

調整格式後,重新建置的畫面如下圖,是不是美觀許多呢?

image

 

各位如果點選檢視此頁的原始碼,可以發現系統已經幫我們自動寫好了以下的程式,你會發現LightSwitch考慮的真的很周詳,他並非直接接入資料庫,而是先暫存於BookListItemProperty屬性中,帶使用者按下儲存時,才會寫入資料庫。

 

using System;
using System.Linq;
using System.IO;
using System.IO.IsolatedStorage;
using System.Collections.Generic;
using Microsoft.LightSwitch;
using Microsoft.LightSwitch.Framework.Client;
using Microsoft.LightSwitch.Presentation;
using Microsoft.LightSwitch.Presentation.Extensions;

namespace LightSwitchApplication
{
    public partial class CreateNewBookListItem
    {
        partial void CreateNewBookListItem_InitializeDataWorkspace(global::System.Collections.Generic.List<global::Microsoft.LightSwitch.IDataService> saveChangesTo)
        {
            // Write your code here.
            this.BookListItemProperty = new BookListItem();
        }

        partial void CreateNewBookListItem_Saved()
        {
            // Write your code here.
            this.Close(false);
            Application.Current.ShowDefaultScreen(this.BookListItemProperty);
        }


    }
}

 

不過既然這一頁是新增書籍,右側清單就不應該還有新增、刪除、修改的功能,所以我們可以回到設計介面中,把這些功能按鈕都移除。

image

剛才設計的是新增書籍的頁面,若是我們要產生一張書籍管理的總功能頁面,那麼我們就要使用「List and Detail Screen」。

image

 

其中將書籍清單切換為Picture and Text控制項,設計方法與剛才其實很類似。

image

 

因為這一頁是書籍管理的總頁面,因此請勾選「Use Read-only Controls」以管控使用者不能直接修改內容。

image

此時設計的頁面看起來好像與之前那一頁很接近,其實不然。各位可以發現他實作了Master-Detail的效果,當左側點選了某一本書籍,則右側會出現那本書籍的明細資訊。

image

image

但是若您點選左側書籍清單上方的加號,此時跳出來的新增書籍頁面是系統自己預設的視窗,而且不能直接修改,因此我們接下來就要做一些調整,讓按下家耗時,跳出來的是剛才我們設計的新增書籍頁面。

image

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

此時在書籍管理主頁的書籍清單上方找到Command Bar,點選「加入…」按右鍵選取「Override Code」。

image

 

此時會跳至程式碼區域,我們可以自行撰寫程式碼已覆蓋原有預設的功能。不過不用擔心,因為LightSwitch已經把功能包裝好現成的方法了,因此叫用非常簡單。要跳至指定頁面,系統已經包裝成「Application.Show[頁面名稱]」的方法。

 

image

 

 

using System;
using System.Linq;
using System.IO;
using System.IO.IsolatedStorage;
using System.Collections.Generic;
using Microsoft.LightSwitch;
using Microsoft.LightSwitch.Framework.Client;
using Microsoft.LightSwitch.Presentation;
using Microsoft.LightSwitch.Presentation.Extensions;
namespace LightSwitchApplication
    {

    public partial class BookListListDetail
        {



        partial void BookListItemListAddAndEditNew_Execute()
            {
            Application.ShowCreateNewBookListItem();

            }
    }
}

 

 

 

此外,如果我們希望在書籍管理主頁上方Ribbon也夠出現新增書籍的功能圖示,此時只需要找到Screen Command Bar,點選「New Button」。

image

 

此時可以設定要連結到此按鈕的方法,在此我們新增一個「ShowCreateNewBook」方法。

image

 

在屬性視窗可以設定這個按鈕的顯示名稱以及對應圖示圖片(建議使用PNG格式)。

image

 

接著點選此按鈕按右鍵,選取「Edit Execute Code」,其內容與剛才的新增書籍的自訂程式碼相同。

image

 

namespace LightSwitchApplication
    {

    public partial class BookListListDetail
        {



        partial void BookListItemListAddAndEditNew_Execute()
            {
            Application.ShowCreateNewBookListItem();

            }

        partial void ShowCreateNewBook_Execute()
            {
            Application.ShowCreateNewBookListItem();

            }
    }
}

如此一來就能輕鬆實作了如同Ribbon的效果。使用者不管點選Ribbon上的圖示清單上的加號,都可以跳到新增書籍的頁面。

image

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Allan Yiin

CTO, AsiaMiner