在非連接配接模式下,主要讨論以下對象:DataAdapter。
DataAdpater的作用是在實體存儲模式的資料和記憶體之間進行資料傳遞。DataTable是用在記憶體中表示資料庫表。DataSet是記憶體中表示資料庫(表、表關系的集合)。DataView是用于在記憶體中表示資料庫視圖。
DataAdapter對象在背景使用DataReader對象從資料庫中擷取資料;DataView對象來對資料進行過濾和排序;DataTable對象可以用來跟蹤資料記錄的改變情況,并決定是否接受或者拒絕這些改變。
DataAdapter對象在實體資料庫和記憶體資料表之間起橋梁的作用。一般用DataAdapter對象從資料庫擷取資料并裝入DataTable對象中,也通過DataAdapter對象将DataTable對象中資料的修改寫回到實體資料庫。
例1: 一個簡單的DataAdapter對象的使用
=== App_Code\DawnDataObject.cs ===
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: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