天天看點

溫故知新ASP.NET 2.0(C#)(8) - DataSourceControl(資料源控件)

溫故知新ASP.NET 2.0(C#)(8) - DataSourceControl(資料源控件)

介紹

在 ASP.NET 2.0 中有幾個新的資料源控件,例如,SqlDataSource、ObjectDataSource、XmlDataSource、AccessDataSource 和 SiteMapDataSource。它們全都可以用來從它們各自類型的資料源中檢索資料,并且可以綁定到各種資料綁定控件。資料源控件減少了為檢索和綁定資料甚至對資料進行排序、分頁或編輯而需要編寫的自定義代碼的數量。

其中 ObjectDataSource 控件可針對各種基礎資料存儲區(如 SQL 資料庫或 XML)啟用聲明性資料綁定模型。因為頁開發人員也常常将資料檢索(也可能包含業務邏輯)封裝在一個元件對象中,進而在呈現頁和資料提供程式之間引入另一個層。ObjectDataSource 控件允許開發人員使用此傳統的三層結構構造應用程式,同時仍然能夠利用 ASP.NET 中的聲明性資料綁定模型的易用性優點。

關鍵

1、在資料層建立 強類型的DataSet和TableAdapter,TableAdapter查詢可以使用現有的存儲過程。注:直接把表或存儲過程拖進來會自動建立TableAdapter

2、中間層的類用[System.ComponentModel.DataObject]聲明為資料元件,CRUD方法分别對應[DataObjectMethod(DataObjectMethodType.Insert)],[DataObjectMethod(DataObjectMethodType.Select)],[DataObjectMethod(DataObjectMethodType.Update)],[DataObjectMethod(DataObjectMethodType.Delete)] 

3、web層使用ObjectDataSource展現資料,ObjectDataSource就相當于一個代理。ObjectDataSource隻是查找具有比對的參數名稱的方法,它不會使用參數的 Type 或 Size,而隻是對參數的名稱進行比對

4、其它

  ·<asp:Parameter />有ConvertEmptyStringToNull屬性,預設是true。另外還有Direction屬性

  ·注意<asp:BoundField />的這幾個屬性NullDisplayText,HtmlEncode,ApplyFormatInEditMode,InsertVisible,DataFormatString,ReadOnly

  ·DataKeyNames有多個值的話用“,”分隔,用<asp:ControlParameter />綁定的話給其加一個“PropertyName”屬性,值類似如下“SelectedDataKey.Values[0]”

  ·關于綁定:簡單屬性<%# custID %>;集合<asp:ListBox id="List1" datasource='<%# myArray %>' runat="server">;表達式<%# ( customer.FirstName + " " + customer.LastName ) %>;方法<%# GetBalance(custID) %> 

  ·<%# Eval("field1") %> 和 <%# Bind("field1") %>,Eval是單向綁定,Bind是雙向邦定

  ·<asp:ObjectDataSource />有一個OldValuesParameterFormatString屬性一般不用,不過如果要處理樂觀并發之類的就會用到。當該屬性的值為“original_{0}”的時候“original_參數名”則為初始值

  ·還有一些如程式設計方式給參數指派,錯誤處理,得到傳回值之類的請看源碼

示例

相關存儲過程和資料層略,見源碼

單例模式的實作

App_Code/Singleton.cs

using System; 

using System.Data; 

using System.Configuration; 

using System.Web; 

using System.Web.Security; 

using System.Web.UI; 

using System.Web.UI.WebControls; 

using System.Web.UI.WebControls.WebParts; 

using System.Web.UI.HtmlControls; 

/// <summary> 

/// Singleton 的摘要說明 

/// </summary> 

public class Singleton<T> where T : new() 

        public static T Instance 

        { 

                get { return SingletonCreator.instance; } 

        } 

        class SingletonCreator 

                internal static readonly T instance = new T(); 

}

中間層代碼

App_Code/Test.cs

using TestDatabaseTableAdapters; 

using System.ComponentModel; 

/// Test 的摘要說明 

[DataObject] 

public class Test 

        [DataObjectMethod(DataObjectMethodType.Select, true)] 

        public TestDatabase.TestDataTable GetTest() 

                return Singleton<TestTableAdapter>.Instance.GetTest(); 

        [DataObjectMethod(DataObjectMethodType.Select, false)] 

        public TestDatabase.TestDataTable GetTestById(int id) 

                return Singleton<TestTableAdapter>.Instance.GetTestById(id); 

        [DataObjectMethod(DataObjectMethodType.Insert, true)] 

        public int?[] InsertTest(int? parentId, string name, DateTime? publishTime, decimal? price, bool? isGood, out int? minId) 

                // 僅為說明如何做錯誤處理 

                if (String.IsNullOrEmpty(name)) 

                        throw new ArgumentException("參數不能是空", "name"); 

                int? id = null; 

                int? count = null; 

                minId = null; 

                Singleton<TestTableAdapter>.Instance.InsertTest(parentId, name, publishTime, price, isGood, ref id, refcount, ref minId); 

                return new int?[] { id, count }; 

        [DataObjectMethod(DataObjectMethodType.Delete, true)] 

        public int? DeleteTest(int id) 

                int? rowAffected; 

                rowAffected = Singleton<TestTableAdapter>.Instance.DeleteTest(id); 

                return rowAffected; 

        [DataObjectMethod(DataObjectMethodType.Update, true)] 

        public int? UpdateTest(int? id, int? parentId, string name, DateTime? publishTime, decimal? price, bool? isGood) 

                rowAffected = Singleton<TestTableAdapter>.Instance.UpdateTest(id, parentId, name, publishTime, price, isGood); 

DataSourceControl/Test.aspx

<%@ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="Test.aspx.cs" 

        Inherits="DataSourceControl_Test" Title="資料源控件測試" %> 

<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server"> 

        <p> 

                <asp:Label ID="lblMsg" runat="server" ForeColor="red" /> 

        </p> 

        <table cellpadding="6"> 

                <tr> 

                        <td valign="top"> 

                                <asp:DetailsView ID="DetailsView1" runat="server" AllowPaging="True" AutoGenerateRows="False" 

                                        DataKeyNames="Id" DataSourceID="ObjectDataSource1" Height="50px" Width="125px" OnItemInserted="DetailsView1_ItemInserted"> 

                                        <Fields> 

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

                                                        SortExpression="Id" /> 

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

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

                                                <asp:BoundField DataField="PublishTime" HeaderText="PublishTime" SortExpression="PublishTime" 

                                                        InsertVisible="False" /> 

                                                <asp:BoundField DataField="Price" HeaderText="Price" SortExpression="Price" DataFormatString="{0:c}" HtmlEncode="False" /> 

                                                <asp:CheckBoxField DataField="IsGood" HeaderText="IsGood" SortExpression="IsGood" /> 

                                                <asp:CommandField ShowInsertButton="True" /> 

                                        </Fields> 

                                </asp:DetailsView> 

                        </td> 

                                <asp:DetailsView ID="DetailsView2" runat="server" Height="50px" Width="125px" AutoGenerateRows="False" DataKeyNames="Id" DataSourceID="ObjectDataSource2"> 

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

                                                <asp:BoundField DataField="Price" HeaderText="Price" SortExpression="Price" DataFormatString="{0:c}" HtmlEncode="false" /> 

                </tr> 

        </table> 

                <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="Id" 

                        DataSourceID="ObjectDataSource1" AllowPaging="True" AllowSorting="True" OnRowUpdating="GridView1_RowUpdating"> 

                        <Columns> 

                                <asp:CommandField ShowDeleteButton="True" ShowEditButton="True" ShowSelectButton="True" /> 

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

                                        SortExpression="Id" /> 

                                <asp:BoundField DataField="ParentId" HeaderText="ParentId" SortExpression="ParentId" 

                                        NullDisplayText="我的值是NULL" /> 

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

                                <asp:BoundField DataField="PublishTime" HeaderText="PublishTime" SortExpression="PublishTime" 

                                        ReadOnly="true" /> 

                                <asp:BoundField DataField="Price" HeaderText="Price" SortExpression="Price" DataFormatString="{0:c}" HtmlEncode="false" ApplyFormatInEditMode="True" /> 

                                <asp:CheckBoxField DataField="IsGood" HeaderText="IsGood" SortExpression="IsGood" /> 

                        </Columns> 

                </asp:GridView> 

        <asp:ObjectDataSource ID="ObjectDataSource1" runat="server" SelectMethod="GetTest" 

                TypeName="Test" InsertMethod="InsertTest" DeleteMethod="DeleteTest" UpdateMethod="UpdateTest" 

                OnInserting="ObjectDataSource1_Inserting" OnInserted="ObjectDataSource1_Inserted"> 

                <InsertParameters> 

                        <%--ConvertEmptyStringToNull屬性預設為true--%> 

                        <asp:Parameter Name="parentId" Type="Int32" ConvertEmptyStringToNull="true" /> 

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

                        <asp:Parameter Name="publishTime" Type="DateTime" /> 

                        <asp:Parameter Name="price" Type="Decimal" /> 

                        <asp:Parameter Name="isGood" Type="Boolean" /> 

                        <asp:Parameter Direction="Output" Name="minId" Type="Int32" /> 

                </InsertParameters> 

                <DeleteParameters> 

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

                </DeleteParameters> 

                <UpdateParameters> 

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

                </UpdateParameters> 

        </asp:ObjectDataSource> 

        <asp:ObjectDataSource ID="ObjectDataSource2" runat="server" OldValuesParameterFormatString="original_{0}" 

                SelectMethod="GetTestById" TypeName="Test"> 

                <SelectParameters> 

                        <asp:ControlParameter ControlID="GridView1" Name="id" PropertyName="SelectedValue" 

                                Type="Int32" /> 

                </SelectParameters> 

</asp:Content>

DataSourceControl/Test.aspx.cs

using System.Collections; 

public partial class DataSourceControl_Test : System.Web.UI.Page 

        protected void Page_Load(object sender, EventArgs e) 

        protected void ObjectDataSource1_Inserting(object sender, ObjectDataSourceMethodEventArgs e) 

                // 程式設計方式給參數指派 

                if (e.InputParameters["publishTime"] == null) 

                { 

                        e.InputParameters["publishTime"] = DateTime.Now; 

                } 

        protected void ObjectDataSource1_Inserted(object sender, ObjectDataSourceStatusEventArgs e) 

                // 錯誤處理 

                if (e.Exception != null) 

                        if (e.Exception.InnerException != null) 

                        { 

                                Exception inner = e.Exception.InnerException; 

                                if (inner is ArgumentException) 

                                { 

                                        string paramName = ((ArgumentException)inner).ParamName; 

                                        lblMsg.Text = string.Concat("參數 ", paramName, " 有問題"); 

                                } 

                        } 

                else 

                        int?[] ary = (int?[])e.ReturnValue; 

                        lblMsg.Text = "新插入資訊的ID是:" + ary[0].ToString(); 

                        lblMsg.Text += "<br />資料總數是:" + ary[1].ToString(); 

                        lblMsg.Text += "<br />最小ID是:" + e.OutputParameters["minId"].ToString(); 

        protected void DetailsView1_ItemInserted(object sender, DetailsViewInsertedEventArgs e) 

                        // 錯誤已處理 

                        e.ExceptionHandled = true; 

                        // DetailsView保持插入狀态 

                        e.KeepInInsertMode = true; 

        protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e) 

                // 價格格式轉換為decimal格式 

                if (e.NewValues["Price"] != null) 

                        e.NewValues["Price"] = decimal.Parse(e.NewValues["Price"].ToString(), System.Globalization.NumberStyles.Currency); 

     本文轉自webabcd 51CTO部落格,原文連結:http://blog.51cto.com/webabcd/344889,如需轉載請自行聯系原作者