天天看點

與ObjectDataSource共舞

4,ORM元件XCode(與ObjectDataSource共舞)

XCode為了能更友善的解決大部分問題,不得不“屈身”于ObjectDataSource。

先上一個經典例子(ObjectDataSource+GridView)(ObjectDataSource):

<asp:GridView ID="GridView1" runat="server" AllowPaging="True" AllowSorting="True"

    AutoGenerateColumns="False" DataKeyNames="ID" DataSourceID="ObjectDataSource1"

    EnableModelValidation="True">

    <Columns>

        <asp:BoundField DataField="ID" HeaderText="ID" InsertVisible="False" ReadOnly="True"

            SortExpression="ID" />

        <asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" />

        <asp:BoundField DataField="ParentID" HeaderText="ParentID" SortExpression="ParentID" />

        <asp:BoundField DataField="test" HeaderText="test" SortExpression="test" />

        <asp:BoundField DataField="Description" HeaderText="Description" SortExpression="Description" />

    </Columns>

</asp:GridView>

<asp:ObjectDataSource ID="ObjectDataSource1" runat="server" DataObjectTypeName="PurpleSun.Center.Area"

    DeleteMethod="Delete" EnablePaging="True" InsertMethod="Insert" OldValuesParameterFormatString="original_{0}"

    SelectCountMethod="FindCountByName" SelectMethod="FindAllByName" SortParameterName="orderClause"

    TypeName="PurpleSun.Center.Area" UpdateMethod="Save">

    <SelectParameters>

        <asp:Parameter Name="name" Type="String" />

        <asp:Parameter Name="value" Type="Object" />

        <asp:Parameter Name="orderClause" Type="String" />

        <asp:Parameter Name="startRowIndex" Type="Int32" />

        <asp:Parameter Name="maximumRows" Type="Int32" />

    </SelectParameters>

</asp:ObjectDataSource>

下面用截圖示範整個過程:

拖GridView和ObjectDataSource

與ObjectDataSource共舞

選中ObjectDataSource,注意右上角的智能标記

與ObjectDataSource共舞

配置資料源

與ObjectDataSource共舞

這裡隻列出資料元件,為什麼這裡隻有我們的Area類?為什麼?我們看看實體類

與ObjectDataSource共舞

就是DataObject特性起的作用,應該說,所有加了該特性的類,都會被當作資料元件在ObjectDataSource配置裡面出現。當然,不加DataObject特性也是可以的,但是在ObjectDataSource配置的時候,就不能勾選資料元件了,那樣會列出所有類(是的,所有類)。

選擇Area類,繼續

與ObjectDataSource共舞

繼續猜測,這裡能列出這些方法,應該也是有特性的,那就是DataObjectMethod特性啦。

與ObjectDataSource共舞

第一個參數代表方法類型(查詢、插入、更新、删除),第二個參數表示是否預設方法,預設方法會在配置ObjectDataSource時被預設選中。

當然啦,另外三個配置頁也是有的(這裡以Update為例)

與ObjectDataSource共舞
與ObjectDataSource共舞

最後一步定義參數,在這裡就不定義了

與ObjectDataSource共舞

可以看到,左邊已經列出了前面選擇的Select方法的所有參數。

來看看一個神奇的地方

與ObjectDataSource共舞

ObjectDataSource可以把查詢參數綁定到Cookie、控件、Request.Form、Request.QueryString、Session等。我們一般綁定到控件,做查詢的時候非常有用。每一個查詢項作為一個參數,然後在這裡綁定到對應的控件;也經常綁定到QueryString,比如表單頁面編輯資料的時候,這裡綁定主鍵,然後就能把相應的對象找出來。

這裡神奇的地方就在于綁定。需要做複雜查詢的時候,可以在界面上放置查詢控件

與ObjectDataSource共舞

然後編寫一個對應的查詢方法,當然要加上DataObjectMethod特性了,然後在ObjectDataSource配置的時候把參數和控件綁定起來

與ObjectDataSource共舞

(關于這類進階查詢後面專門介紹,這裡僅僅是為了說明綁定的神奇)

綁定的神奇就在于,界面控件問資料源控件(如ObjectDataSource)要資料的時候,資料源控件開始着手準備參數,反射讀取綁定控件的值作為參數,并轉為相應的類型,然後再反射調用實體類的查詢方法(如Search)。

到這裡,ObjectDataSource的基本配置已經完成,絕大多數ORM架構對ObjectDataSource的支援,也僅僅是到這裡而已。而XCode的模型,是完全滿足ObjectDataSource要求的,下面繼續進階功能

與ObjectDataSource共舞

這是ObjectDataSource控件屬性中的分頁類屬性,第一項啟用分頁,第三項指定用于查詢所有記錄數的方法(前面提到過查詢方法是成對出現的,這裡的FindAllByName和FindCountByName就是一對),至于第二項和第四項,是不是很熟悉?

與ObjectDataSource共舞
與ObjectDataSource共舞

這兩個方法,一個傳回實體集合,一個傳回總行數,而參數則是一摸一樣。這就是ObjectDataSource對分頁查詢的要求,如果沒有第二個,ObjectDataSource也能提供查詢資料功能,但是就沒辦法分頁了。

回過頭了,仔細看看最後兩個參數的名稱,是不是跟ObjectDataSource屬性中的那兩個一摸一樣?是以,XCode使用這兩個名字作為參數名,正是這個原因。如果查詢方法使用的不是這兩個參數,那麼在配置ObjectDataSource的時候自己跟着改就是了。

這兩個參數,第一個是從哪一行開始讀資料,第二個是傳回的最大行數,其實就是每頁行數。這種分頁結構,跟别的絕大部分分頁控件什麼的都不相同。是以,并不是XCode的分頁另類,而是别的分頁才是另類,XCode是正統(哈哈)。

除了分頁屬性,再看看一個排序屬性

與ObjectDataSource共舞

正是查詢方法的倒數第三個參數。GridView在排序的時候,會給這個參數傳遞ID Asc或Name Desc等。而查詢方法内部,正是根據這個參數,以及兩個分頁參數,拼接SQL語句進行查詢的。

至此,ObjectDataSource配置完成。打開GridView的智能标記,選擇ObjectDataSource控件作為資料源,GridView即可自動生成列

與ObjectDataSource共舞

當然,這個列并不是資料庫字段,而是實體類的屬性。

在智能标記面闆上可以看到,啟用分頁和啟用排序可以勾選了,正是因為剛才在ObjectDataSource中配置好了。都勾上!

運作,看效果

與ObjectDataSource共舞

界面很醜,不過那是美工的事情了。試試分頁(打開OrmDebug開關,檢視SQL語句)

與ObjectDataSource共舞

執行的SQL:

Select * From (Select row_number() over(Order By ID Desc) as row_number, * From Area) XCode_Temp_b Where row_Number Between 71 And 80

這是XCode生成的分頁語句,因為現在測試環境是SQL2008,随意生成了row_number的分頁,如果是别的資料庫,就會不同了。但那是XCode的事情,開發者不需要關心。

再試試在分頁的基礎上排序(點選Name):

與ObjectDataSource共舞

    執行的SQL:

Select * From (Select row_number() over(Order By Name) as row_number, * From Area) XCode_Temp_b Where row_Number Between 81 And 90

    排序已經改為Order By Name了,再點一次Name,執行SQL:

Select * From (Select row_number() over(Order By Name DESC) as row_number, * From Area) XCode_Temp_b Where row_Number Between 81 And 90

    完全滿足要求!

    BTW:GridView那裡,其實還可以啟用編輯和删除的,因為配置ObjectDataSource的時候,預設已經配置了編輯和删除的方法。

    最後,目的已經達到,或許你還沒有發現,到這裡我們還沒有手工編寫任何代碼呢!

    XCode與ObjectDataSource共舞可以得到非常美的開發效果,但是,上面的模式,已經是三年前的做法了,我們現在有了更好的工業級的做法——批量生産!

大石頭

新生命開發團隊

2010-08-24 13:25

我不相信神話,我隻相信汗水!我不相信命運,我隻相信雙手!