天天看點

asp.net學習之ado.net(無連接配接模式中的DataAdapter)

    在非連接配接模式下,主要讨論以下對象:DataAdapter。

    DataAdpater的作用是在實體存儲模式的資料和記憶體之間進行資料傳遞。DataTable是用在記憶體中表示資料庫表。DataSet是記憶體中表示資料庫(表、表關系的集合)。DataView是用于在記憶體中表示資料庫視圖。 

    DataAdapter對象在背景使用DataReader對象從資料庫中擷取資料;DataView對象來對資料進行過濾和排序;DataTable對象可以用來跟蹤資料記錄的改變情況,并決定是否接受或者拒絕這些改變。 

     DataAdapter對象在實體資料庫和記憶體資料表之間起橋梁的作用。一般用DataAdapter對象從資料庫擷取資料并裝入DataTable對象中,也通過DataAdapter對象将DataTable對象中資料的修改寫回到實體資料庫。

例1: 一個簡單的DataAdapter對象的使用

=== App_Code\DawnDataObject.cs ===

asp.net學習之ado.net(無連接配接模式中的DataAdapter)
asp.net學習之ado.net(無連接配接模式中的DataAdapter)

Code

public class Movie_Disconnect

{

    private static readonly string  _connectionstring;

    static Movie_Disconnect()

    {

        _connectionstring = WebConfigurationManager.ConnectionStrings["DawnEnterpriseDBConnectionString"].

            ConnectionString.ToString();

    }

    public DataTable GetAll()

        // 初始化DataAdapter

        SqlDataAdapter dad = new SqlDataAdapter("Select Id,Title,Director from Movies", _connectionstring);

        // 初始化Table

        DataTable dt = new DataTable();

        dad.Fill(dt);

        return dt;

=== showMovies.aspx

asp.net學習之ado.net(無連接配接模式中的DataAdapter)
asp.net學習之ado.net(無連接配接模式中的DataAdapter)

<asp:GridView ID="GridView1" runat="server" DataSourceID="ObjectDataSource1">

</asp:GridView>

<asp:ObjectDataSource ID="ObjectDataSource1" TypeName="DawnDataObject.Movie_Disconnect" SelectMethod="GetAll" runat="server">

</asp:ObjectDataSource> 

    在例1中,我們看到了如何構造一個SqlDataAdapter對象,并且使用Fill方法把資料表填到一個DataTable中。它看起來是像下面這樣子的:

SqlDataAdapter dad = new SqlDataAdapter("Select Id,Title,Director from Movies", _connectionstring);

DataTable dt = new DataTable();

dad.Fill(dt);

    在以上的例子中,看不到SqlConnection,SqlCommand對象的出象,其實,它們還是隐含存在的,這些對象被SqlDataAdapter對象調用了而已,就連SqlConnection對象的Open()方法的調用也由SqlDataAdapter對象來代勞了。

    如果要顯式使用SqlConnection,SqlCommand對象,可以像以下代碼這樣:

例2: SqlAdapter對象的另外構造方法

public DataTable GetAll()

    DataTable dt = new DataTable();

    using(SqlConnection conn = new SqlConnection(_connectionstring)) {

        SqlCommand command = new SqlCommand("Select Id,Title,Director from Movies", conn);

        SqlDataAdapter dad = new SqlDataAdapter(command);

    return dt;

}

    以上,可以看出,SqlDataAdapter構造函數可以傳入一個SqlCommand對象。在ADO.Net中SqlDataAdapter構造函數可以使用以下幾種方法進行構造

     ● SqlDataAdapter(): 無參數,構造後,可以給SqlDataAdapter對象的SelectCommand屬性配置設定一個SqlCommand對象。

         作為補充,SqlDataAdapter還有UpdateCommand、DeleteCommand、InsertCommand屬性,這些屬性在後面會提到。

     ● SqlDataAdapter(string commandText, SqlConnection connection): 第一個參數為T-SQL語句,第二個參數為一個SqlConnection對象。

        使用這個構造函數時,不需要顯式聲明SqlCommand對象。

     ● SqlDataAdapter(string commandText, string connectionString): 例1使用的方法,不需要顯式聲明SqlConnection與SqlCommand對象

     ● SqlDataAdapter(SqlCommand command): 例2使用的方法。

     DataAdapter對象的Fill方法,該方法不止可以傳入DataTable作為參數,也可以傳入DataSet作為參數。

     DataAdapter對象的FillSchema方法,可以向DataSet/DataTable參數添加現有的資料庫限制。

     3.1 指派到DataSet

         因為DataSet是DataTable的集合,是以可以Fill多張表到DataSet對象中。

例3: Fill多張資料表到DataSet對象

private void buttonFillData_Click(object sender, EventArgs e)

    DataSet userData = new DataSet();

    using (SqlConnection testConnection = new SqlConnection(connectionString))  {

        SqlCommand testCommand = testConnection.CreateCommand();

        testCommand.CommandText = "Select FirstName, LastName from userTable; Select PermissionType from PermissionsTable";

        SqlDataAdapter dataAdapter = new SqlDataAdapter(testCommand);

        dataAdapter.Fill(userData);

    } // testConnection.Dispose called automatically.

    3.2 Fill方法的重載

       預設的,當調用SqlDataAdapter.Fill(DataSet)時,并沒有指定Table名,是以,要想取得DataSet中的DataTable對象,需要使用Index序号。

       也可以指定當Fill進DataSet時,相應表的TableName屬性,當需要指定TableName屬性時,調用以下Fill方法:

        public int Fill(DataSet dataSet, string srcTable);

      以下的例子是它們之間的差別:

例4: 調用Fill方法填充到DataSet時,指定TableName屬性

    protected void Page_Load(object sender, EventArgs e)

        if (!IsPostBack)

        {

            string _connectionstring = WebConfigurationManager.ConnectionStrings["DawnEnterpriseDBConnectionString"].

            DataSet ds = new DataSet();

            using (SqlConnection conn = new SqlConnection(_connectionstring))

            {

                SqlCommand command = new SqlCommand("Select Id,Title,Director from Movies", conn);

                SqlDataAdapter dad = new SqlDataAdapter(command);

                dad.Fill(ds, "Movies");  // 調用Fill方法時,使用TableName

                dad.SelectCommand = new SqlCommand("select Id,name from MovieCategories", conn);

                dad.Fill(ds);   // 為使用TableName

                GridView1.DataSource = ds.Tables["Movies"]; // 使用TableName進行指定

                GridView1.DataBind();

                GridView2.DataSource = ds.Tables[1];  // 使用inde進行指定

                GridView2.DataBind();

            }

        }

    3.3 DataAdapter的FillSchema方法

       SqlDataAdapter 類提供 Fill 和 FillSchema 兩種方法,這對于加載這些資料很關鍵。這兩種方法均可将資訊加載到 DataSet 中。Fill 加載資料本身,而 FillSchema 加載有關特定表的所有可用的中繼資料(如列名、主鍵和限制)。處理資料加載的正确方式是先運作 FillSchema,後運作 Fill。例如:

daAuthors.FillSchema(dsPubs,SchemaType.Source, "Authors");

daAuthors.Fill(dsPubs,"Authors");

        具體的參照以下幾篇文章:

        例5:調用FillSchema方法:

//一般先用FillSchema來填入詳細的中繼資料資訊,再用Fill來填充資料,例如:

sqlDataAdapter1.FillSchema(dataSet1,SchemaType.Source,"authors");

sqlDataAdapter1.Fill(dataSet1,"authors");

DataColumn[] colArr;

colArr = dataSet1.Tables["authors"].PrimaryKey;

MessageBox.Show("Column Count: " + colArr.Length.ToString());

for(int i = 0; i < colArr.Length; i++)

    MessageBox.Show(colArr[i].ColumnName + "   " + colArr[i].DataType.ToString());

    在上例中,如果不調用FillSchema, 預設情況下不會填如PrimaryKey資訊。

    另外,DataAdapter還有一個MissingSchemaAction屬性,該屬性可以接受以下Enum值:

      ● Add---在添加新行時向DataTable中添加必須的附加列(預設值)

      ● AddWithKey---在添加新行時向DataTAble中添加所有必須的列。

      ● Error---在添加新行時,如果此行不比對現在的DataTable,就引發一個錯誤。

      ● Ignore---在添加新行時,如果此行中包含DataTable中沒有的列,那麼忽略多餘的列。

    ds.MissingSchemaAction = MissingSchemaAction.AddWithkey