版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
1、第十章 數(shù)據(jù)庫應用程序開發(fā)ADO.Net程序?qū)崿F(xiàn)典型的數(shù)據(jù)庫應用程序開發(fā)。l數(shù)據(jù)庫連接l數(shù)據(jù)加載l數(shù)據(jù)的簡單和復雜綁定l對DataSet數(shù)據(jù)瀏覽、插入、刪除、確認和取消lDataSet的表達式列和數(shù)據(jù)檢索lDataSet中數(shù)據(jù)表的關聯(lián)l對數(shù)據(jù)庫的更新:CommandBuilder的更新機制報表設計-CrystalReportSQL Server基本數(shù)據(jù)準備:建立數(shù)據(jù)庫teaching建立下列數(shù)據(jù)表:lStudents:學生表(id,name,classid)lGrade:成績表(id,subid,grade)lClasses:班級表(classid,name)1.1 ADO.NetADO/OL
2、E DB和ODBC關系圖VC+VBDelphiADOOLE DBODBCRDBMSRDBMSE-MailDirectoryServiceADO.NET結構.NET DataProviderDataSetCommandDataReaderParametersConnectionTransactionDataAdapterSelectCommandInsertCommandUpdateCommandDeleteCommandDataTableDataRowCollectionDataColumnCollectionConstraintCollectionDataReaderCollectionDa
3、taBaseXML1.2 實例分析:設計一個Form實現(xiàn)對數(shù)據(jù)表students、subjects和grade編輯和瀏覽功能examplea1程序設計的兩種方式自編程序設計方式:自編程序?qū)嵗痙ataset等對象、設置屬性、動態(tài)連接數(shù)據(jù)庫、實現(xiàn)數(shù)據(jù)綁定、數(shù)據(jù)表關聯(lián)等。可視化設計方式:設計階段通過添加組件,設置組件屬性完成數(shù)據(jù)庫的連接、數(shù)據(jù)綁定以及數(shù)據(jù)表的關聯(lián)等,然后由系統(tǒng)生成部分程序。1.2.1 自編程序方式一)把數(shù)據(jù)庫中數(shù)據(jù)表數(shù)據(jù)顯示在控件中1)連接數(shù)據(jù)庫:teaching (SQL Server)2)數(shù)據(jù)庫中數(shù)據(jù)載入DataSet:加載students3)DataSet中數(shù)據(jù)和控件的綁定:
4、id和TextBox的綁定1)連接數(shù)據(jù)庫:teaching (SQL Server)using System.Data.OleDb;private DataSet dataSet;private OleDbConnection oleDbConnection;private OleDbDataAdapter oleDbDataAdapter;private void ConnectDB() oleDbConnection = new OleDbConnection(Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Inf
5、o=False;Initial Catalog=teaching); oleDbConnection.Open();OleDbConnection中連接字符串:新建teaching.udl文件,雙擊后進入oleDB數(shù)據(jù)鏈接屬性編輯,連接對應數(shù)據(jù)庫并成功進行測試連接后,關閉窗口后teaching.udl中包含了連接字符串。2)數(shù)據(jù)庫中數(shù)據(jù)載入DataSet:加載studentsprivate void LoadData()oleDbDataAdapter = new OleDbDataAdapter(select * from students, oleDbConnection); dataSe
6、t = new DataSet(); oleDbDataAdapter.Fill(dataSet, students);DataSet本身沒有從數(shù)據(jù)庫加載數(shù)據(jù)的能力,必須通過OleDbDataAdapter提供的Fill方法進行加載。在Fill過程中,若dataSet中沒有students,則會自動建立,并把“select * from students”結果載入。3)DataSet中數(shù)據(jù)和控件的綁定:id和TextBox的綁定private void BindingControls() textBox1.DataBindings.Add(text, dataSet, “students.id
7、);textBox1的Text屬性和dataSet中students表的id字段進行綁定。綁定的結果是textBox1的值和dataSet中students表的id值會同步變化。在Form的load事件中執(zhí)行下列語句:ConnectDB();LoadData();BindingControls();二)復雜綁定:classid數(shù)據(jù)取自classes表,提供選擇功能。LoadData中增加下列程序oleDbDataAdapter.SelectCommand = new OleDbCommand(select * from classes,oleDbConnection);oleDbDataAda
8、pter.Fill(dataSet, classes);在BindControls中增加下列程序: comboBox1.DataSource = dataSet.Tablesclasses; ; comboBox1.DisplayMember=name; comboBox1.ValueMember = classid; comboBox1.DataBindings.Add(selectedValue, dataSet, students.classid);三)加入瀏覽功能DataSet中的Table和數(shù)據(jù)庫中數(shù)據(jù)表一樣,沒有行順序的概念,所有沒有提供行號定位的方法和屬性當一個數(shù)據(jù)表數(shù)據(jù)綁定在F
9、orm上的若干控件后,由其BindingContext成員管理從Control類繼承的任意對象的 BindingManagerBase對象集合,通過設置其屬性Position來控制當前顯示的行:this.BindingContextdataSet, students.Position += 1;注意students和控件的綁定方式不能寫成下列形式,這將使Form僅顯示首行內(nèi)容,而無法通過上述方式定位到其他行。(一致性)textBox1.DataBindings.Add(text, dataSet.Tablesstudents, id);首行對應Position=0,當Position=0,再-
10、1屬性值將不變。當Position=總行數(shù)-1,再加1同樣值不變。四)使用綁定對DataSet數(shù)據(jù)表進行插入刪除插入: this.BindingContextdataSet, students.EndCurrentEdit();this.BindingContextdataSet, students.AddNew();界面顯示新增的空行,如綁定的界面控件不允許空值,則界面仍顯示原行內(nèi)容,解決方法是為dataset中該表的列設置缺省值,例如:dataSet.Tables“account”.Columns“happendate”.DefaultValue = DateTime.Today;刪除:t
11、his.BindingContextdataSet, students.RemoveAt(this.BindingContextdataSet, students.Position);取消當前行的修改:this.BindingContextdataSet, students.CancelCurrentEdit();五)通過控件輸入的DataSet數(shù)據(jù)的取消和確認功能控件輸入數(shù)據(jù)與DataSet數(shù)據(jù)同步:this.BindingContextdataSet, “students”.Position值變化或調(diào)用this.BindingContextdataSet, “students”.EndCu
12、rrentEdit()后,界面控件數(shù)據(jù)才寫入DataSet。取消修改:dataSet.RejectChanges():取消dataSet創(chuàng)建或調(diào)用dataSet.AcceptChanges()以后對dataSet所作的修改。接收修改: dataSet.AcceptChanges():接收對dataSet中數(shù)據(jù)所做的修改。dataSet中各表及表中各行對象均有取消和接受修改的上述兩個方法,區(qū)別是其作用的對象范圍不同。六)把DataSet數(shù)據(jù)存入數(shù)據(jù)庫更新數(shù)據(jù)庫中數(shù)據(jù)表的唯一途徑是執(zhí)行SQL的insert、update或delete語句,dataSet中數(shù)據(jù)的修改(表的增、刪、改),要反映到數(shù)據(jù)庫
13、中,必須根據(jù)修改情況產(chǎn)生并執(zhí)行相應的SQL語句。所以要根據(jù)對DataSet數(shù)據(jù)表的修改更新對應數(shù)據(jù)庫中的數(shù)據(jù)表,必須完成下列三部分工作:l標記DataSet中數(shù)據(jù)表做過修改的所有行,并記錄作了何種修改(增、刪、改)。l編寫或生成相應的帶參數(shù)的insert、delete或update語句。l對每個修改行,根據(jù)修改的種類,執(zhí)行相應的更新數(shù)據(jù)庫的語句。1)標記修改行及修改種類在dataSet中表的每一行對象有一個RowState屬性,記錄了該行是否作了修改及作了何種修改的信息:dataSet.Tablesstudents.Rows0.RowState其值可為:DataRowState.Added/M
14、odified/Deleted和Unchanged。當dataSet中表數(shù)據(jù)載入后,各行的狀態(tài)為Unchanged,當對表中某行進行修改后,會根據(jù)修改類型自動改變該行的狀態(tài)。在調(diào)用AcceptChanges后,對應行狀態(tài)恢復到Unchanged狀態(tài)。由于更新數(shù)據(jù)庫的update方法是依據(jù)該狀態(tài)來確定哪些行要修改和做什么修改,所以在用dataSet數(shù)據(jù)更新數(shù)據(jù)庫前,不要調(diào)用用AcceptChanges。2)編寫或生成相應的帶參數(shù)的SQL語句(1) 使用OleDBCommandBuilder產(chǎn)生更新數(shù)據(jù)庫的帶參數(shù)的SQL語句OleDbCommandBuilder可根據(jù)oleDBDataAdapte
15、r中的Select Command中的select語句,即調(diào)用Fill方法時執(zhí)行的select語句,生成帶參數(shù)的update、delete或insert語句。在窗口類中增加成員:OleDbCommandBuilder oleDbCommandBuilder; 在LoadData加載(Fill)students數(shù)據(jù)語句后加:oleDbCommandBuilder = new OleDbCommandBuilder(oleDbDataAdapter);實例化實例化oleDbCommandBuilder,并把并把oleDbDataAdapter作為其屬性作為其屬性DataAdapter值,在要生成值
16、,在要生成SQL語句前,語句前, oleDbCommandBuilder必必須能訪問非空的須能訪問非空的oleDbDataAdapter.SelectCommand。在生成在生成SQL語句前,首先會執(zhí)行上述的語句前,首先會執(zhí)行上述的select語句,以獲得對應表的語句,以獲得對應表的列名信息,為生成做準備。列名信息,為生成做準備。生成的生成的SQL語句將存放在該類的基類對應的三個語句將存放在該類的基類對應的三個private屬性中:它們屬性中:它們是是UpdateCommand、DeleteCommand和和InsertCommand。生成生成SQL語句的條件(如語句的條件(如UpdateCo
17、mmand)l基類對應的屬性為空(如基類對應的屬性為空(如UpdateCommand=null)ldataSet對應數(shù)據(jù)表中存在對應狀態(tài)的行(如存在對應數(shù)據(jù)表中存在對應狀態(tài)的行(如存在Modified狀狀態(tài)的行)態(tài)的行)在下列調(diào)用中會調(diào)用在下列調(diào)用中會調(diào)用oleDbCommandBuilder中生成中生成SQL語句的程序(并非在初始化的時候):語句的程序(并非在初始化的時候):l調(diào)用其方法調(diào)用其方法GetUpdateCommand或或GetDeleteCommand或或GetInsertCommand時,返回對應的命令串時,返回對應的命令串。l調(diào)用其屬性調(diào)用其屬性DataAdapter值對象值
18、對象oleDbDataAdapter所包含的所包含的方法:方法:oleDbDataAdapter.Update(dataSet, “students”);該該語句用生成的語句用生成的SQL語句及語句及dataSet修改過的數(shù)據(jù)更新數(shù)據(jù)表。修改過的數(shù)據(jù)更新數(shù)據(jù)表。比較特別是比較特別是oleDbDataAdapter是是oleDbCommandBuilder的的DataAdapter屬性值,其方法卻要調(diào)用擁有它的對象方法以生屬性值,其方法卻要調(diào)用擁有它的對象方法以生成成SQL語句,這種調(diào)用方法見語句,這種調(diào)用方法見“3)更新數(shù)據(jù)庫)更新數(shù)據(jù)庫”后的例。后的例。生成帶參數(shù)的生成帶參數(shù)的SQL語句條件
19、和時機:語句條件和時機:加入生成SQL語句的語句: 在LoadData中實例化oleDbCommndBuilder后調(diào)用下列語句以生成帶參數(shù)的更新數(shù)據(jù)庫的SQL語句。oleDbCommandBuilder.GetDeleteCommand();oleDbCommandBuilder.GetUpdateCommand();oleDbCommandBuilder.GetInsertCommand();由于LoadData中先使用oleDbDataAdapter加載了students表,然后同樣使用它加載classes表,所以如沒有上述語句,則在update時,oleDbCommandBuilder
20、. DataAdapter指向的oleDataAdapter的SelectCommand屬性的CommandText為Select * from classes,所以將生成對classes的更新語句。而上述語句生成了關于students的SQL語句,在update時發(fā)現(xiàn)oleDbCommandBuilder中已存在這些語句,就不會再生成關于classes的更新語句。OleDbCommandBuilder其他說明:由上可知,SQL語句一但生成,改變oleDbDataAdapter的SelectCommand屬性,由于生成SQL語句的第一個條件不滿足,不會改變oldDbCommandBuilder
21、中已生成的SQL語句。oleDbCommandBuilder.RefreshSchema()可用于清空生成的SQL語句(基類屬性),可使生成SQL語句的第一個條件滿足。使用OleDbCommandBuilder的限制:select語句必須為單表的查詢,包含主鍵,但不包含只讀列(如計算列)。為了生成 INSERT、UPDATE 或 DELETE 語句,OleDbCommandBuilder 會自動使用 SelectCommand 屬性來檢索所需的元數(shù)據(jù)集,以獲得如列名等信息,所以會降低執(zhí)行效率。 (2)編寫更新數(shù)據(jù)庫的SQL如果Fill一個DataSet數(shù)據(jù)表對應的select語句牽涉多個表,就
22、不能使用oleDbCommandBuilder生成更新數(shù)據(jù)庫的SQL語句,必須手工編寫。目標:在Form的下方用DataGrid顯示當前學生的各門課的名稱及成績,可以修改成績但不能添加和刪除,點擊保存按鈕后保存修改內(nèi)容。增加下列Form類成員:private DataRelation dataRelation; /students和grade的關聯(lián)private OleDbDataAdapter oleDbDataAdapter1;/用于grade表把grade數(shù)據(jù)加載到DataSetprivate void LoadGrade() oleDbDataAdapter1 = new OleDbD
23、ataAdapter(); oleDbDataAdapter1.SelectCommand = new OleDbCommand(select a.id,a.subid,b.subname,a.grade from grade a,subjects b where a.subid=b.subid, oleDbConnection); oleDbDataAdapter1.Fill(dataSet, “grade”);/dataSet中產(chǎn)生中產(chǎn)生grade表表/update時調(diào)用的時調(diào)用的update語句,其中語句,其中“?”表示定位參數(shù)(非命名參數(shù)),依次表示定位參數(shù)(非命名參數(shù)),依次和和/下
24、面下面oleDbDataAdapter1.UpdateCommand.Parameters中的參數(shù)對應。中的參數(shù)對應。oleDbDataAdapter1.UpdateCommand = new OleDbCommand(update grade set grade=? where id=? and subid=?,oleDbConnection);/以下語句定義執(zhí)行以下語句定義執(zhí)行update時三個參數(shù)來自時三個參數(shù)來自dataSet.grade(由(由fill語句第二個參語句第二個參數(shù)確定)表的哪個列數(shù)確定)表的哪個列 /定義第一個參數(shù):名為定義第一個參數(shù):名為“grade”,對定位參數(shù),參
25、數(shù)按次序?qū)Q無用對定位參數(shù),參數(shù)按次序?qū)?,名稱無用OleDbParameter gradeParameter = new OleDbParameter(grade, OleDbType.Integer);/該參數(shù)數(shù)據(jù)來源該參數(shù)數(shù)據(jù)來源grade列列 gradeParameter.SourceColumn = “grade”;/數(shù)據(jù)取修改后數(shù)據(jù),此語句可省略數(shù)據(jù)取修改后數(shù)據(jù),此語句可省略 gradeParameter.SourceVersion = DataRowVersion.Current;/缺省缺省/定義第二個參數(shù)定義第二個參數(shù)id:數(shù)據(jù)取修改前數(shù)據(jù)數(shù)據(jù)取修改前數(shù)據(jù)OleDbPar
26、ameter idParameter = new OleDbParameter(id, OleDbType.Char,6);idParameter.SourceColumn = “id”; /數(shù)據(jù)來源于數(shù)據(jù)來源于id列列idParameter.SourceVersion = DataRowVersion.Original;/定義第三個參數(shù)定義第三個參數(shù)subid:數(shù)據(jù)取修改前數(shù)據(jù),同時指定數(shù)據(jù)來源于數(shù)據(jù)取修改前數(shù)據(jù),同時指定數(shù)據(jù)來源于subid列列OleDbParameter subidParameter = new OleDbParameter(subid, OleDbType.Char,
27、6,subid);subidParameter.SourceVersion = DataRowVersion.Original;/將三個參數(shù)依次加入?yún)?shù)表,作為將三個參數(shù)依次加入?yún)?shù)表,作為update語句中的三個參數(shù)語句中的三個參數(shù)oleDbDataAdapter1.UpdateCommand.Parameters.Add(gradeParameter);oleDbDataAdapter1.UpdateCommand.Parameters.Add(idParameter);oleDbDataAdapter1.UpdateCommand.Parameters.Add(subidParamete
28、r);/建立名為建立名為students_grade的兩表關系,聯(lián)結條件的兩表關系,聯(lián)結條件students.id=grade.iddataRelation = new DataRelation(students_grade, dataSet.Tablesstudents.Columnsid, dataSet.Tablesgrade.Columnsid);/將關系加入將關系加入dataSet.Relation中中dataSet.Relations.Add(dataRelation);在在LoadData方法最后加方法最后加LoadGrade()設置并顯示DataGrid:private voi
29、d SetDataGrid() DataGrid dataGrid = new DataGrid(); /dataGrid與與Panel1對齊并設置大小相同對齊并設置大小相同dataGrid.SetBounds(panel1.Location.X, panel1.Location.Y + panel1.Size.Height, panel1.Size.Width, panel1.Size.Height);/把把dataGrid加入加入Formthis.Controls.Add(dataGrid);dataGrid.CaptionText = “成績成績”;dataGrid.DataSource
30、 = dataSet;/students_grade為為LoadGrid中已建立的中已建立的students和和grade關系名,其關系名,其/中中students為父表,如此定義使為父表,如此定義使dataGrid僅顯示僅顯示students的當前學生的當前學生/成績成績,而非所有而非所有grade行。行。 dataGrid.DataMember = “students.students_grade”; /定義兩個在定義兩個在DataGrid中顯示的列:課程名稱和成績中顯示的列:課程名稱和成績 DataGridTextBoxColumn column1=new DataGridTextBox
31、Column(); DataGridTextBoxColumn column2=new DataGridTextBoxColumn(); column1.MappingName=subname; column1.HeaderText=課程名稱課程名稱; column2.MappingName=grade;column2.HeaderText=成績成績;/把兩個列加入把兩個列加入dataGridTableStyle.GradeColumnStylesDataGridTableStyle dataGridTableStyle=new DataGridTableStyle();dataGridTab
32、leStyle.GridColumnStyles.Add(column1); dataGridTableStyle.GridColumnStyles.Add(column2);/若不設置下列屬性,若不設置下列屬性,dataGrid將顯示將顯示select所有列,上述設置不起作用所有列,上述設置不起作用dataGridTableStyle.MappingName = grade;dataGrid.TableStyles.Add(dataGridTableStyle);在Form的Load事件中加入:SetDataGrid()3)更新數(shù)據(jù)庫使用下列語句更新數(shù)據(jù)庫使用下列語句更新數(shù)據(jù)庫(保存按鈕的(
33、保存按鈕的click事件)事件): /確保把和確保把和dataSet中中students及及grade綁定的控件數(shù)據(jù)寫入綁定的控件數(shù)據(jù)寫入dataSetthis.BindingContextdataSet,“students”.EndCurrentEdit(); this.BindingContextdataSet, grade.EndCurrentEdit();oleDbDataAdapter.Update(dataSet, students);oleDbDataAdapter1.Update(dataSet,grade);Update執(zhí)行流程如下:執(zhí)行流程如下:l如如oleDbDataAd
34、apter關聯(lián)了一個關聯(lián)了一個oleDbCommandBuilder (即前(即前者為后者的一個屬性,判斷方法如下例者為后者的一個屬性,判斷方法如下例owner!=null) ,若后者尚若后者尚未生成更新數(shù)據(jù)庫的未生成更新數(shù)據(jù)庫的SQL語句(其基類對象相應屬性為空),則生語句(其基類對象相應屬性為空),則生成。成。l執(zhí)行更新語句:若程序已設置執(zhí)行更新語句:若程序已設置oleDbDataAdapter中的屬性如中的屬性如UpdateCommand中的中的update語句,則執(zhí)行該語句(即由程序員編語句,則執(zhí)行該語句(即由程序員編寫數(shù)據(jù)庫的更新語句),否則則執(zhí)行寫數(shù)據(jù)庫的更新語句),否則則執(zhí)行ol
35、dDbCommandBuilder基類基類對象屬性所存儲的對象屬性所存儲的update語句語句下頁示例如何在一個對象下頁示例如何在一個對象(oleDbCommandBuilder)的屬性的屬性值值對象對象(oleDbDataAdapter)的方法中調(diào)用擁有它的對象的方法中調(diào)用擁有它的對象( oleDbCommandBuilder )的方法(生成的方法(生成SQL的方法的方法)例:commandBuilder對象的屬性值對象dataAdapter的update方法調(diào)用commandBuilder的方法GetSQL public class DataAdapter public object ow
36、ner; public string update() if (owner!=null) return (CommandBuilder)owner).GetSQL(); else return null; public class CommandBuilder private DataAdapter dataAdapter; private string UpdateText; public CommandBuilder(DataAdapter dataAdapter) this.dataAdapter = dataAdapter; this.dataAdapter.owner = this;
37、 public string GetSQL() UpdateText=update students set name=wangwhere id=01; return UpdateText; 調(diào)用示例:若沒有第二個語句,即調(diào)用示例:若沒有第二個語句,即dataAdapter不和不和commandBuilder關關聯(lián),仍能調(diào)用聯(lián),仍能調(diào)用update,但返回但返回null。DataAdapter dataAdapter = new DataAdapter();CommandBuilder commandBuilder = new CommandBuilder(dataAdapter);Messa
38、geBox.Show(dataAdapter.update();七)DataSet表的表達式列目標:在窗口上動態(tài)顯示該學生的平均成績。對DataSet中的students,增加計算列avggradec,其值為子表grade中grade字段值的平均值,并動態(tài)綁定到對應的TextBox。 private void AddAvgGradeToStudents() if (dataSet.Tablesstudents.Columnsavggradec = null) dataSet.Tablesstudents.Columns.Add(avggradec); dataSet.Tablesstudent
39、s.Columnsavggradec.Expression =avg(child.grade); textBox3.DataBindings.Add(text, dataSet, students.avggradec); 在LoadData最后加AddAvgGradeToStudents()設置textBox3為readonly。修改成績,平均成績即刻更新。DataColumn.Expresion獲取或設置表達式,用于篩選行、計算列中的值或創(chuàng)建聚合列,假設在grade表中已增加列c。計算列:dataSet.Tablesgrade.Columns c.Expression= grade*0.9;
40、聚合列:支持sum、max、min和count等聚合函數(shù),見上例。為篩選器指定表達式:值為true/false。dataSet.Tablesgrade.Columnsc.Expression= subid=sub001;Expression中對父表或子表關系引用通過在列名稱前面加 Parent,就可以在表達式中引用父表。例如,Parent.Price 引用父表的名為 Price 的列。通過在列名稱前面加一個 Child,就可以在表達式中引用子表中的列。因為子關系可以返回多行,所以必須在聚合函數(shù)中包括對子列的引用。例如,Sum(Child.Price) 將返回子表中名為 Price 的列的總和。
41、如果某個表有多個子表,則語法是:Child(RelationName)。例如,如果某個表有兩個子表,父表名為 Customers,一個子表名為一個子表名為 Orders,則 DataRelation對象被命名為 Customers2Orders,引用將為:Avg(Child(Customers2Orders).Quantity)八)使用Tag屬性綁定列目標:使用RadioButton選擇性別,但Students.sex類型為bit,0表示男,1表示女。需要在一個GroupBox中放兩個RadioButton,其Text分別為“男”和“女”,而實際只需要獲得一個RadioButton的Check
42、ed狀態(tài)就能確定性別。由于值不同,所以不能使用RadioButton的Text屬性和students.sex綁定,可用Tag屬性與其綁定。這樣的設置必須完成兩部分工作:lTag值改變時(瀏覽時)要對RadioButton的狀態(tài)作相應改變lRadioButton狀態(tài)改變時要改變Tag值RadioButton狀態(tài)改變時改變Tag值在RadioButton的CheckedChanged事件中實現(xiàn): if (radioButton1.Checked) radioButton1.Tag = false; else radioButton1.Tag = true;Students的sex屬性類型為bit,
43、其值只能取0和1,與radioButton1.Tag綁定后,Tag的值為true和false。Tag值改變時要對RadioButton的狀態(tài)作相應改變:首先實現(xiàn)下列方法:首先實現(xiàn)下列方法: private void SetSexRadioButton(object sender, EventArgs e) if (radioButton1.Tag.ToString() = ) radioButton1.Checked = false; radioButton2.Checked = false; return; if (radioButton1.Tag.ToString() = False) r
44、adioButton1.Checked = true; radioButton2.Checked = false; else radioButton1.Checked = false; radioButton2.Checked = true; 何時調(diào)用該方法:方案一:在窗口打開后(Load事件)及按瀏覽按鈕時,調(diào)用5次。方案二:在窗口打開后(Load事件)和this.BindingContextdataSet, “students”對象的PositionChanged事件中調(diào)用,調(diào)用2次。l在BindingControls最后加:radioButton1.DataBindings.Add(ta
45、g, dataSet, students.sex);this.BindingContextdataSet, students.PositionChanged += SetSexRadioButton;l在Form的Load事件中加:SetSexRadioButton(this, null);九)使用程序?qū)ataSet中數(shù)據(jù)表的插入、刪除、修改和檢索。以上對dataSet的數(shù)據(jù)表的操作是通過綁定來實現(xiàn)的,修改控件中數(shù)據(jù)則自動更新數(shù)據(jù)表中數(shù)據(jù),插入和刪除則是通過this.BindingContextdataSet, “students”的AddNew方法和RemoveAt方法實現(xiàn)。直接對Data
46、Set中數(shù)據(jù)表操作方法如下:修改:dataSet.Tablesstudents.Rows0name = zhp;插入: dataSet.Tablesstudents.Rows.Add(DataRow row)或dataSet.Tablesstudents.Rows.InsertAt(DataRow row,int pos)刪除:dataSet.Tablesstudents.Rowspos.Delete()dataSet.Tablesstudents.Rows.RemoveAt(int pos)前者對應行作刪除標記,后者作實際刪除,所以使用后者用update無法更新數(shù)據(jù)庫兩者當和子表建立rela
47、tion,均會對子表的對應行作刪除標記dataSet.Tables“account”.Rowspos.Delete()和 this.BindingContextdataSet, “account”.RemoveAt(pos)中Pos的區(qū)別在刪除按鈕的click事件中分別用下列程序:int pos = this.BindingContextdataSet, account.Position;1)dataSet.Tablesaccount.Rowspos.Delete()2)this.BindingContextdataSet, account.RemoveAt(pos)現(xiàn)象:假設account表
48、中共4行第一種做法:先刪第3行,有效,界面上顯示第4行內(nèi)容,再刪,無效。反之,先刪第4行,有效,界面上顯示第3行內(nèi)容,再刪,有效。第二種做法:正確。分析第一種處理錯誤原因:.Net的基本處理規(guī)則:l界面和數(shù)據(jù)表綁定,界面不顯示已作刪除標記的行l(wèi)當前顯示行非最后一行,對該行執(zhí)行delete(),則顯示下一行,當前行號不變l當前行為最后一行,對該行執(zhí)行delete(),則顯示上一行,當前行號-1上例刪除第3行后,顯示第4行,當前行仍為3,繼續(xù)執(zhí)行刪除,還是刪除第3行上例刪除最后一行后,顯示第3行,當前行為第3行,繼續(xù)刪除,則刪除第3行,顯示第2行這個例子說明,這樣的處理,存在漏洞。數(shù)據(jù)集數(shù)據(jù)被刪除
49、時與之綁定界面數(shù)據(jù)的同步變化(與通過bindingcontext刪除一致)數(shù)據(jù)集中數(shù)據(jù)表某行被刪,如該行正好顯示在界面上,界面檢測到當前行對應數(shù)據(jù)表中的狀態(tài)為刪除,則判斷:l數(shù)據(jù)集中存在下一行,則界面上下一行成為當前顯示行,當前行行號不變。l數(shù)據(jù)集中沒有下一行,則界面上上一行成為當前顯示行,當前行行號-1l如刪除后數(shù)據(jù)表為空,結果為如何?數(shù)據(jù)庫中主碼為自增類型的問題問題:l數(shù)據(jù)加載到dataset后,自增列一般不需要用戶設置,新增一行后,dataset中該列一般為空,保存后數(shù)據(jù)庫自動產(chǎn)生值,然后如果馬上又刪除該行,此時dataset中該主碼值仍為空,保存時執(zhí)行delete語句時無法定位,導致錯
50、誤(提示為并發(fā)錯誤)解決方法:l在dataset中也設置該列為自動增加列,但如在保存前做多次增加和刪除后,無法保證dataset中新增行的該列的值連續(xù)(可驗證:增3行,刪中間行,剩下兩行就會跳號,而存入數(shù)據(jù)庫時數(shù)據(jù)庫仍會自動生成該號,為連號)l保存后從數(shù)據(jù)庫重新加載所有數(shù)據(jù)l保存后從數(shù)據(jù)庫加載新增行的數(shù)據(jù),是否可行待驗證l新增或刪除前先提示是否保存,必須保存后才能進行新增和刪除操作,確保數(shù)據(jù)庫和dataset數(shù)據(jù)一致性,但變成在線式l如設計時數(shù)據(jù)庫庫中該列不使用自增,而在dataset中設置自增,就避免了此問題的發(fā)生。設計的重要性Dataset中設置列為自增列: dataSet.Tablesa
51、ccount.Columnsseqno.AutoIncrement = true;dataSet.Tablesaccount.Columnsseqno.AutoIncrementSeed = Convert.ToInt32(dataSet.Tablesaccount.RowsdataSet.Tablesaccount.Rows.Count - 1seqno.ToString() + 1;dataSet.Tablesaccount.Columnsseqno.AutoIncrementStep = 1;在界面上新增加的行不被刪除的情況下能保證dataset中新增行的該列值和存入數(shù)據(jù)庫后的該列值數(shù)據(jù)
52、的一致性。檢索:DataSet中的Table提供了下列兩種方法檢索符合條件的行,返回符合條件的行。Select方法:DataRow dataRow = dataSet.Tablesstudents.Select(id= + textBox4.Text + );/使用dataRow.GetLength(0)獲得符合條件的行數(shù)Find方法:檢索主鍵值,必須先建立主鍵,見下例。DataRow dataRow = dataSet.Tables“students”.Rows.Find(textBox1.Text);/找不到返回null方法比較:Select檢索條件任意,可返回多行,F(xiàn)ind方法只能對建立
53、的主鍵值檢索,返回最多一行,由于表總關于主鍵排序,所以檢索速度較select快很多。檢索實例:目標:輸入學生編號,按“檢索”按鈕后若該學生不存在,則提示,若存在,則顯示該學生信息:分析:定位控件顯示的行的唯一方法是設置Binding Context的Position屬性,而Find和Select返回的是dataRow,余下的問題是如何由已知行dataRow獲得該行在table中的行序號,.Net提供了該方法:dataSet.Tablesstudents.Rows.IndexOf(dataRow);以下使對學生編號檢索的程序: private void button13_Click(object
54、 sender, EventArgs e) int idx; DataColumn dataColumn; dataColumn = new DataColumn1; dataColumn0 = dataSet.Tablesstudents.Columnsid; dataSet.Tables“students”.PrimaryKey = dataColumn; /至此為設置主鍵至此為設置主鍵 DataRow dataRow=dataSet.Tablesstudents.Rows.Find(textBox4.Text); if (dataRow = null) MessageBox.Show(沒
55、有發(fā)現(xiàn)符合條件的行!沒有發(fā)現(xiàn)符合條件的行!); else idx=dataSet.Tablesstudents.Rows.IndexOf(dataRow); this.BindingContextdataSet, students.Position = idx; 1.2.2 可視化設計構造DataSet:前面的設計方式,必須在程序運行后,才能確定DataSet的結構(包含哪些Table和Relation等),.Net可以使用XML文件構建DataSet類,這使程序設計和運行可不依賴于和數(shù)據(jù)庫的連接,并且使數(shù)據(jù)庫結構修改后,只要修改對應的XML文件,而不必修改程序。類型化DataSet和非類型化
56、DataSet:前者在程序設計時定義(可編寫或生成)DataSet類的內(nèi)部結構,編譯時進行類型檢查,所以類型安全,后者則在程序運行時產(chǎn)生DataSet對象的內(nèi)部結構(1.2.1中例子的方式),可能由于數(shù)據(jù)類型不一致而使運行時更容易發(fā)生錯誤。設計步驟:根據(jù)數(shù)據(jù)庫中表結構生成DataSet1.XSD文件:使用菜單Add New Item/ DataSet進入可視化地構建DataSet模式(schema),可把Server Explorer中數(shù)據(jù)表拖入及使用工具欄中的Relation建立數(shù)據(jù)表之間的聯(lián)系,然后保存(XML格式)。依據(jù)上面生成的XSD文件產(chǎn)生DataSet類和對象定義:在Form中加入
57、工具欄中DataSet,選擇Typed dataset。Name選擇examplea1. DataSet1(即對應上面XSD文件),系統(tǒng)根據(jù)XSD文件內(nèi)容在dataSet11. Designer. cs文件中產(chǎn)生類定義DataSet1,并在Form1.Designer. cs中定義了該類的對象dataset11。通過設置控件的DataBindings屬性(可選dataset11數(shù)據(jù)項)實施綁定等設置,對應程序也在Form1.Desig ner. cs文件中生成。兩種類型DataSet數(shù)據(jù)的訪問的區(qū)別:非類型化DataSet(弱類型DataSet)dataSet.Tables“students”
58、.Columns“id”或dataSet.Tables0.Columns0類型化DataSet(強類型DataSet)dataSet.students.idColumn1.2.3 報表設計:CrystalReport基本原理:使用報表設計器設計報表,設計內(nèi)容存入特殊格式的CrystalReport.rpt文件中,該報表文件也可供其他語言(C+或VB)開發(fā)的程序使用。同時生成了一個繼承于ReportClass的報表類定義文件CrystalReport.cs,其中包含了該類與rpt文件的關聯(lián),用戶通過該類實現(xiàn)對上述設計報表的操作。在該類定義文件中可以加入工具箱中的組件(把組件拖入CrystalRe
59、port.csDesigner頁面)。報表通過可視化控件CrystalReportViewer顯示。用戶只要實例化一個報表類對象,并把包含數(shù)據(jù)的DataSet對象傳給它,由報表類完成對rpt文件的解析,獲取數(shù)據(jù)并在CrystalReportViewer中顯示報表。報表的數(shù)據(jù)來源-用非類型化DataSet產(chǎn)生XSD使用CrystalReport,在設計階段必須確定報表的數(shù)據(jù)來源,即必須構建DataSet框架,報表設計時各數(shù)據(jù)項可選自構建好的DataSet。在程序運行時,通過報表類的SetDataSource方法把實例化的DataSet(包含數(shù)據(jù)的)對象傳遞給報表,該DataSet必須包含報表設計
60、時所用到數(shù)據(jù)項,或保證兩者數(shù)據(jù)模型完全一致。由于本例DataSet為非類型化,可使用下列語句把DataSet模型輸出到XSD文件,供報表設計用:dataSet.WriteXmlSchema(dataset1.xsd);一)設計List報表:學生基本信息表(CryStalReport1)構建報表數(shù)據(jù)源:l在項目中加入DataSet1.XSD:在Solution Explorer中右擊項目名,選擇Add/Existing Item,選擇前面生成DataSet1.XSD文件。l系統(tǒng)會生成DataSet1.Designer.cs,其中定義了名為NewDataSet類,該類為依據(jù)XSD文件構造的類型化D
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年益陽市兩型建設投資集團有限公司招聘備考題庫及參考答案詳解1套
- 2025年太湖縣關工委、老年大學公開招聘編外工作人員備考題庫及一套答案詳解
- 寧德市蕉城區(qū)教育局公布2026年公開補充招聘緊缺急需人才的備考題庫及參考答案詳解
- 2025年華北石油管理局總醫(yī)院應屆畢業(yè)生招聘24人備考題庫及一套答案詳解
- 2025年上海外國語大學附屬外國語學校松江云間中學校園招聘備考題庫及參考答案詳解一套
- 2025年長春光華學院工程技術研發(fā)中心招聘備考題庫及參考答案詳解一套
- 中國鐵路廣州局集團有限公司2026年招聘普通高校畢業(yè)生備考題庫(二)及參考答案詳解
- 2025年茂名市茂南區(qū)現(xiàn)場公開招聘急需緊缺人才6人備考題庫及1套完整答案詳解
- 2025年臨沂市檢察機關公開招聘47人備考題庫及答案詳解參考
- 2025年蚌埠市中欣國有控股有限公司公開招聘副總經(jīng)理備考題庫及答案詳解參考
- TRICON安全控制系統(tǒng)
- 幼兒園小班音樂歌唱《碰一碰》課件
- 中醫(yī)診療技術操作規(guī)程
- CJT 340-2016 綠化種植土壤
- 二年級上冊口算練習1000道
- 2023年11月浙江省慈溪技師學院(慈溪杭州灣中等職業(yè)學校)公開招聘1名派遣制工作人員筆試歷年高頻考點-難、易錯點薈萃附答案帶詳解
- 農(nóng)業(yè)水價綜合改革
- 23秋國家開放大學《液壓氣動技術》形考任務1-3參考答案
- 廣東省通用安裝工程綜合定額(2018)Excel版
- 21ZJ111 變形縫建筑構造
- 2023-2024學年四川省涼山州小學語文五年級期末高分試卷詳細參考答案解析
評論
0/150
提交評論