10.CS架構(gòu)斷開(kāi)式應(yīng)用程序設(shè)計(jì)入門.ppt_第1頁(yè)
10.CS架構(gòu)斷開(kāi)式應(yīng)用程序設(shè)計(jì)入門.ppt_第2頁(yè)
10.CS架構(gòu)斷開(kāi)式應(yīng)用程序設(shè)計(jì)入門.ppt_第3頁(yè)
10.CS架構(gòu)斷開(kāi)式應(yīng)用程序設(shè)計(jì)入門.ppt_第4頁(yè)
10.CS架構(gòu)斷開(kāi)式應(yīng)用程序設(shè)計(jì)入門.ppt_第5頁(yè)
已閱讀5頁(yè),還剩54頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、第十章 數(shù)據(jù)庫(kù)應(yīng)用程序開(kāi)發(fā),ADO.Net 程序?qū)崿F(xiàn)典型的數(shù)據(jù)庫(kù)應(yīng)用程序開(kāi)發(fā)。 數(shù)據(jù)庫(kù)連接 數(shù)據(jù)加載 數(shù)據(jù)的簡(jiǎn)單和復(fù)雜綁定 對(duì)DataSet數(shù)據(jù)瀏覽、插入、刪除、確認(rèn)和取消 DataSet的表達(dá)式列和數(shù)據(jù)檢索 DataSet中數(shù)據(jù)表的關(guān)聯(lián) 對(duì)數(shù)據(jù)庫(kù)的更新:CommandBuilder的更新機(jī)制 報(bào)表設(shè)計(jì)-CrystalReport,SQL Server基本數(shù)據(jù)準(zhǔn)備:,建立數(shù)據(jù)庫(kù)teaching 建立下列數(shù)據(jù)表: Students:學(xué)生表(id,name,classid) Grade:成績(jī)表(id,subid,grade) Classes:班級(jí)表(classid,name),1.1 ADO.Ne

2、tADO/OLE DB和ODBC關(guān)系圖,VC+,VB,Delphi,ADO,OLE DB,ODBC,RDBMS,RDBMS,E-Mail,Directory Service,ADO.NET結(jié)構(gòu),1.2 實(shí)例分析:設(shè)計(jì)一個(gè)Form實(shí)現(xiàn)對(duì)數(shù)據(jù)表students、subjects和grade編輯和瀏覽功能examplea1,程序設(shè)計(jì)的兩種方式 自編程序設(shè)計(jì)方式:自編程序?qū)嵗痙ataset等對(duì)象、設(shè)置屬性、動(dòng)態(tài)連接數(shù)據(jù)庫(kù)、實(shí)現(xiàn)數(shù)據(jù)綁定、數(shù)據(jù)表關(guān)聯(lián)等。 可視化設(shè)計(jì)方式:設(shè)計(jì)階段通過(guò)添加組件,設(shè)置組件屬性完成數(shù)據(jù)庫(kù)的連接、數(shù)據(jù)綁定以及數(shù)據(jù)表的關(guān)聯(lián)等,然后由系統(tǒng)生成部分程序。,1.2.1 自編程序方式,一

3、)把數(shù)據(jù)庫(kù)中數(shù)據(jù)表數(shù)據(jù)顯示在控件中 1)連接數(shù)據(jù)庫(kù):teaching (SQL Server) 2)數(shù)據(jù)庫(kù)中數(shù)據(jù)載入DataSet:加載students 3)DataSet中數(shù)據(jù)和控件的綁定:id和TextBox的綁定,1)連接數(shù)據(jù)庫(kù):teaching (SQL Server),using System.Data.OleDb; private DataSet dataSet; private OleDbConnection oleDbConnection; private OleDbDataAdapter oleDbDataAdapter; private void ConnectDB() o

4、leDbConnection = new OleDbConnection(Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=teaching); oleDbConnection.Open(); OleDbConnection中連接字符串:新建teaching.udl文件,雙擊后進(jìn)入oleDB數(shù)據(jù)鏈接屬性編輯,連接對(duì)應(yīng)數(shù)據(jù)庫(kù)并成功進(jìn)行測(cè)試連接后,關(guān)閉窗口后teaching.udl中包含了連接字符串。,2)數(shù)據(jù)庫(kù)中數(shù)據(jù)載入DataSet:加載students,privat

5、e void LoadData() oleDbDataAdapter = new OleDbDataAdapter(select * from students, oleDbConnection); dataSet = new DataSet(); oleDbDataAdapter.Fill(dataSet, students); DataSet本身沒(méi)有從數(shù)據(jù)庫(kù)加載數(shù)據(jù)的能力,必須通過(guò)OleDbDataAdapter提供的Fill方法進(jìn)行加載。 在Fill過(guò)程中,若dataSet中沒(méi)有students,則會(huì)自動(dòng)建立,并把“select * from students”結(jié)果載入。,3)DataS

6、et中數(shù)據(jù)和控件的綁定:id和TextBox的綁定,private void BindingControls() textBox1.DataBindings.Add(text, dataSet, “students.id); textBox1的Text屬性和dataSet中students表的id字段進(jìn)行綁定。 綁定的結(jié)果是textBox1的值和dataSet中students表的id值會(huì)同步變化。 在Form的load事件中執(zhí)行下列語(yǔ)句:ConnectDB();LoadData();BindingControls();,二)復(fù)雜綁定:classid數(shù)據(jù)取自classes表,提供選擇功能。,L

7、oadData中增加下列程序 oleDbDataAdapter.SelectCommand = new OleDbCommand(select * from classes,oleDbConnection); oleDbDataAdapter.Fill(dataSet, classes); 在BindControls中增加下列程序: comboBox1.DataSource = dataSet.Tablesclasses; ; comboBox1.DisplayMember=name; comboBox1.ValueMember = classid; comboBox1.DataBinding

8、s.Add(selectedValue, dataSet, students.classid);,三)加入瀏覽功能,DataSet中的Table和數(shù)據(jù)庫(kù)中數(shù)據(jù)表一樣,沒(méi)有行順序的概念,所有沒(méi)有提供行號(hào)定位的方法和屬性 當(dāng)一個(gè)數(shù)據(jù)表數(shù)據(jù)綁定在Form上的若干控件后,由其BindingContext成員管理從Control類繼承的任意對(duì)象的 BindingManagerBase對(duì)象集合,通過(guò)設(shè)置其屬性Position來(lái)控制當(dāng)前顯示的行: this.BindingContextdataSet, students.Position += 1; 注意students和控件的綁定方式不能寫成下列形式,這將

9、使Form僅顯示首行內(nèi)容,而無(wú)法通過(guò)上述方式定位到其他行。 textBox1.DataBindings.Add(text, dataSet.Tablesstudents, id); 首行對(duì)應(yīng)Position=0,當(dāng)Position=0,再-1屬性值將不變。當(dāng)Position=總行數(shù)-1,再加1同樣值不變。,四)使用綁定對(duì)DataSet數(shù)據(jù)表進(jìn)行插入和刪除,插入: this.BindingContextdataSet, students.EndCurrentEdit(); this.BindingContextdataSet, students.AddNew(); 刪除: this.Bindin

10、gContextdataSet, students.RemoveAt(this.BindingContextdataSet, students.Position); 取消當(dāng)前行的修改: this.BindingContextdataSet, students.CancelCurrentEdit();,五)通過(guò)控件輸入的DataSet數(shù)據(jù)的取消和確認(rèn)功能,控件輸入數(shù)據(jù)與DataSet數(shù)據(jù)同步: this.BindingContextdataSet, “students”.Position值變化或調(diào)用this.BindingContextdataSet, “students”.EndCurrent

11、Edit()后,界面控件數(shù)據(jù)才寫入DataSet。 取消修改: dataSet.RejectChanges():取消dataSet創(chuàng)建或調(diào)用dataSet.AcceptChanges()以后對(duì)dataSet所作的修改。 接收修改: dataSet.AcceptChanges():接收對(duì)dataSet中數(shù)據(jù)所做的修改。 dataSet中各表及表中各行對(duì)象均有取消和接受修改的上述兩個(gè)方法,區(qū)別是其作用的對(duì)象范圍不同。,六)把DataSet數(shù)據(jù)存入數(shù)據(jù)庫(kù),更新數(shù)據(jù)庫(kù)中數(shù)據(jù)表的唯一途徑是執(zhí)行SQL的insert、update或delete語(yǔ)句,dataSet中數(shù)據(jù)的修改(表的增、刪、改),要反映到數(shù)據(jù)

12、庫(kù)中,必須根據(jù)修改情況產(chǎn)生并執(zhí)行相應(yīng)的SQL語(yǔ)句。所以要根據(jù)對(duì)DataSet數(shù)據(jù)表的修改更新對(duì)應(yīng)數(shù)據(jù)庫(kù)中的數(shù)據(jù)表,必須完成下列三部分工作: 標(biāo)記DataSet中數(shù)據(jù)表做過(guò)修改的所有行,并記錄作了何種修改(增、刪、改)。 編寫或生成相應(yīng)的帶參數(shù)的insert、delete或update語(yǔ)句。 對(duì)每個(gè)修改行,根據(jù)修改的種類,執(zhí)行相應(yīng)的更新數(shù)據(jù)庫(kù)的語(yǔ)句。,1)標(biāo)記修改行及修改種類,在dataSet中表的每一行對(duì)象有一個(gè)RowState屬性,記錄了該行是否作了修改及作了何種修改的信息: dataSet.Tablesstudents.Rows0.RowState 其值可為:DataRowState.Ad

13、ded/Modified/Deleted和Unchanged。 當(dāng)dataSet中表數(shù)據(jù)載入后,各行的狀態(tài)為Unchanged,當(dāng)對(duì)表中某行進(jìn)行修改后,會(huì)根據(jù)修改類型自動(dòng)改變?cè)撔械臓顟B(tài)。在調(diào)用AcceptChanges后,對(duì)應(yīng)行狀態(tài)恢復(fù)到Unchanged狀態(tài)。 由于更新數(shù)據(jù)庫(kù)的update方法是依據(jù)該狀態(tài)來(lái)確定哪些行要修改和做什么修改,所以在用dataSet數(shù)據(jù)更新數(shù)據(jù)庫(kù)前,不要調(diào)用用AcceptChanges。,2)編寫或生成相應(yīng)的帶參數(shù)的SQL語(yǔ)句(1) 使用OleDBCommandBuilder產(chǎn)生更新數(shù)據(jù)庫(kù)的帶參數(shù)的SQL語(yǔ)句,OleDbCommandBuilder可根據(jù)oleDBD

14、ataAdapter中的Select Command中的select語(yǔ)句,即調(diào)用Fill方法時(shí)執(zhí)行的select語(yǔ)句,生成帶參數(shù)的update、delete或insert語(yǔ)句。 在窗口類中增加成員:OleDbCommandBuilder oleDbCommandBuilder; 在LoadData加載(Fill)students數(shù)據(jù)語(yǔ)句后加: oleDbCommandBuilder = new OleDbCommandBuilder(oleDbDataAdapter); 實(shí)例化oleDbCommandBuilder,并把oleDbDataAdapter作為其屬性DataAdapter值,在要生

15、成SQL語(yǔ)句前, oleDbCommandBuilder必須能訪問(wèn)非空的oleDbDataAdapter.SelectCommand。 在生成SQL語(yǔ)句前,首先會(huì)執(zhí)行上述的select語(yǔ)句,以獲得對(duì)應(yīng)表的列名信息,為生成做準(zhǔn)備。 生成的SQL語(yǔ)句將存放在該類的基類對(duì)應(yīng)的三個(gè)private屬性中:它們是UpdateCommand、DeleteCommand和InsertCommand。,生成SQL語(yǔ)句的條件(如UpdateCommand) 基類對(duì)應(yīng)的屬性為空(如UpdateCommand=null) dataSet對(duì)應(yīng)數(shù)據(jù)表中存在對(duì)應(yīng)狀態(tài)的行(如存在Modified狀態(tài)的行) 在下列調(diào)用中會(huì)調(diào)用

16、oleDbCommandBuilder中生成SQL語(yǔ)句的程序(并非在初始化的時(shí)候): 調(diào)用其方法GetUpdateCommand或GetDeleteCommand或GetInsertCommand時(shí),返回對(duì)應(yīng)的命令串。 調(diào)用其屬性DataAdapter值對(duì)象oleDbDataAdapter所包含的方法:oleDbDataAdapter.Update(dataSet, “students”);該語(yǔ)句用生成的SQL語(yǔ)句及dataSet修改過(guò)的數(shù)據(jù)更新數(shù)據(jù)表。 比較特別是oleDbDataAdapter是oleDbCommandBuilder的DataAdapter屬性值,其方法卻要調(diào)用擁有它的對(duì)象

17、方法以生成SQL語(yǔ)句,這種調(diào)用方法見(jiàn)“3)更新數(shù)據(jù)庫(kù)”后的例。,生成帶參數(shù)的SQL語(yǔ)句條件和時(shí)機(jī):,加入生成SQL語(yǔ)句的語(yǔ)句:,在LoadData中實(shí)例化oleDbCommndBuilder后調(diào)用下列語(yǔ)句以生成帶參數(shù)的更新數(shù)據(jù)庫(kù)的SQL語(yǔ)句。 oleDbCommandBuilder.GetDeleteCommand(); oleDbCommandBuilder.GetUpdateCommand(); oleDbCommandBuilder.GetInsertCommand(); 由于LoadData中先使用oleDbDataAdapter加載了students表,然后同樣使用它加載classe

18、s表,所以如沒(méi)有上述語(yǔ)句,則在update時(shí),oleDbCommandBuilder. DataAdapter指向的oleDataAdapter的SelectCommand屬性的CommandText為Select * from classes,所以將生成對(duì)classes的更新語(yǔ)句。 而上述語(yǔ)句生成了關(guān)于students的SQL語(yǔ)句,在update時(shí)發(fā)現(xiàn)oleDbCommandBuilder中已存在這些語(yǔ)句,就不會(huì)再生成關(guān)于classes的更新語(yǔ)句。,OleDbCommandBuilder其他說(shuō)明:,由上可知,SQL語(yǔ)句一但生成,改變oleDbDataAdapter的SelectCommand

19、屬性,由于生成SQL語(yǔ)句的第一個(gè)條件不滿足,不會(huì)改變oldDbCommandBuilder中已生成的SQL語(yǔ)句。 oleDbCommandBuilder.RefreshSchema()可用于清空生成的SQL語(yǔ)句(基類屬性),可使生成SQL語(yǔ)句的第一個(gè)條件滿足。 使用OleDbCommandBuilder的限制:select語(yǔ)句必須為單表的查詢,包含主鍵,但不包含只讀列(如計(jì)算列)。 為了生成 INSERT、UPDATE 或 DELETE 語(yǔ)句,OleDbCommandBuilder 會(huì)自動(dòng)使用 SelectCommand 屬性來(lái)檢索所需的元數(shù)據(jù)集,以獲得如列名等信息,所以會(huì)降低執(zhí)行效率。,(2

20、)編寫更新數(shù)據(jù)庫(kù)的SQL,如果Fill一個(gè)DataSet數(shù)據(jù)表對(duì)應(yīng)的select語(yǔ)句牽涉多個(gè)表,就不能使用oleDbCommandBuilder生成更新數(shù)據(jù)庫(kù)的SQL語(yǔ)句,必須手工編寫。 目標(biāo):在Form的下方用DataGrid顯示當(dāng)前學(xué)生的各門課的名稱及成績(jī),可以修改成績(jī)但不能添加和刪除,點(diǎn)擊保存按鈕后保存修改內(nèi)容。 增加下列Form類成員: private DataRelation dataRelation; /students和grade的關(guān)聯(lián) private OleDbDataAdapter oleDbDataAdapter1;/用于grade表,把grade數(shù)據(jù)加載到DataSet,

21、private void LoadGrade() oleDbDataAdapter1 = new OleDbDataAdapter(); 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)生grade表 /update時(shí)調(diào)用的update語(yǔ)

22、句,其中“?”表示定位參數(shù)(非命名參數(shù)),依次和/下面oleDbDataAdapter1.UpdateCommand.Parameters中的參數(shù)對(duì)應(yīng)。 oleDbDataAdapter1.UpdateCommand = new OleDbCommand(update grade set grade=? where id=? and subid=?,oleDbConnection); /定義執(zhí)行update時(shí)三個(gè)參數(shù)來(lái)自dataSet.grade表的那個(gè)列 /定義第一個(gè)參數(shù):名為“grade”,對(duì)定位參數(shù),參數(shù)按次序?qū)?yīng),名稱無(wú)用 OleDbParameter gradeParameter =

23、 new OleDbParameter(grade, OleDbType.Integer); /該參數(shù)數(shù)據(jù)來(lái)源grade列 gradeParameter.SourceColumn = “grade”; /數(shù)據(jù)取修改后數(shù)據(jù),此語(yǔ)句可省略 gradeParameter.SourceVersion = DataRowVersion.Current;/缺省,/定義第二個(gè)參數(shù)id:數(shù)據(jù)取修改前數(shù)據(jù) OleDbParameter idParameter = new OleDbParameter(id, OleDbType.Char,6); idParameter.SourceColumn = “id”;

24、/數(shù)據(jù)來(lái)源于id列 idParameter.SourceVersion = DataRowVersion.Original; /定義第三個(gè)參數(shù)subid:數(shù)據(jù)取修改前數(shù)據(jù),同時(shí)指定數(shù)據(jù)來(lái)源于subid列 OleDbParameter subidParameter = new OleDbParameter(subid, OleDbType.Char, 6,subid); subidParameter.SourceVersion = DataRowVersion.Original; /將三個(gè)參數(shù)依次加入?yún)?shù)表,作為update語(yǔ)句中的三個(gè)參數(shù) oleDbDataAdapter1.UpdateCom

25、mand.Parameters.Add(gradeParameter); oleDbDataAdapter1.UpdateCommand.Parameters.Add(idParameter); oleDbDataAdapter1.UpdateCommand.Parameters.Add(subidParameter); /建立名為students_grade的兩表關(guān)系,聯(lián)結(jié)條件students.id=grade.id dataRelation = new DataRelation(students_grade, dataSet.Tablesstudents.Columnsid, dataSe

26、t.Tablesgrade.Columnsid); /將關(guān)系加入dataSet.Relation中 dataSet.Relations.Add(dataRelation); 在LoadData方法最后加LoadGrade(),設(shè)置并顯示DataGrid:,private void SetDataGrid() DataGrid dataGrid = new DataGrid(); /dataGrid與Panel1對(duì)齊并設(shè)置大小相同 dataGrid.SetBounds(panel1.Location.X, panel1.Location.Y + panel1.Size.Height, panel

27、1.Size.Width, panel1.Size.Height); /把dataGrid加入Form this.Controls.Add(dataGrid); dataGrid.CaptionText = “成績(jī)”; dataGrid.DataSource = dataSet; /students_grade為L(zhǎng)oadGrid中已建立的students和grade關(guān)系名,其/中students為父表,如此定義使dataGrid僅顯示students的當(dāng)前學(xué)生 /成績(jī),而非所有g(shù)rade行。 dataGrid.DataMember = “students.students_grade”;,/定

28、義兩個(gè)在DataGrid中顯示的列:課程名稱和成績(jī) DataGridTextBoxColumn column1=new DataGridTextBoxColumn(); DataGridTextBoxColumn column2=new DataGridTextBoxColumn(); column1.MappingName=subname; column1.HeaderText=課程名稱; column2.MappingName=grade; column2.HeaderText=成績(jī); /把兩個(gè)列加入dataGridTableStyle.GradeColumnStyles DataGrid

29、TableStyle dataGridTableStyle=new DataGridTableStyle(); dataGridTableStyle.GridColumnStyles.Add(column1); dataGridTableStyle.GridColumnStyles.Add(column2); /若不設(shè)置下列屬性,dataGrid將顯示select所有列,上述設(shè)置不起作用 dataGridTableStyle.MappingName = grade; dataGrid.TableStyles.Add(dataGridTableStyle); 在Form的Load事件中加入:Se

30、tDataGrid(),3)更新數(shù)據(jù)庫(kù),使用下列語(yǔ)句更新數(shù)據(jù)庫(kù)(保存按鈕的click事件): /確保把和dataSet中students及grade綁定的控件數(shù)據(jù)寫入dataSet this.BindingContextdataSet,“students”.EndCurrentEdit(); this.BindingContextdataSet, grade.EndCurrentEdit(); oleDbDataAdapter.Update(dataSet, students); oleDbDataAdapter1.Update(dataSet,grade); Update執(zhí)行流程如下: 如o

31、leDbDataAdapter關(guān)聯(lián)了一個(gè)oleDbCommandBuilder (即前者為后者的一個(gè)屬性,判斷方法如下例owner!=null) ,若后者尚未生成更新數(shù)據(jù)庫(kù)的SQL語(yǔ)句(其基類對(duì)象相應(yīng)屬性為空),則生成。 執(zhí)行更新語(yǔ)句:若程序已設(shè)置oleDbDataAdapter中的屬性如UpdateCommand中的update語(yǔ)句,則執(zhí)行該語(yǔ)句(即由程序員編寫數(shù)據(jù)庫(kù)的更新語(yǔ)句),否則則執(zhí)行oldDbCommandBuilder基類對(duì)象屬性所存儲(chǔ)的update語(yǔ)句 下頁(yè)示例如何在一個(gè)對(duì)象(oleDbCommandBuilder)的屬性值對(duì)象(oleDbDataAdapter)的方法中調(diào)用擁有

32、它的對(duì)象( oleDbCommandBuilder )的方法(生成SQL的方法),例:commandBuilder對(duì)象的屬性值對(duì)象dataAdapter的update方法調(diào)用commandBuilder的方法GetSQL,public class DataAdapter public object owner; public string update() if (owner!=null) return (CommandBuilder)owner).GetSQL(); else return null; public class CommandBuilder private DataAdapt

33、er dataAdapter; private string UpdateText; public CommandBuilder(DataAdapter dataAdapter) this.dataAdapter = dataAdapter; this.dataAdapter.owner = this; public string GetSQL() UpdateText=update students set name=wangwhere id=01; return UpdateText; ,調(diào)用示例:若沒(méi)有第二個(gè)語(yǔ)句,即dataAdapter不和commandBuilder關(guān)聯(lián),仍能調(diào)用up

34、date,但返回null。 DataAdapter dataAdapter = new DataAdapter(); CommandBuilder commandBuilder = new CommandBuilder(dataAdapter); MessageBox.Show(dataAdapter.update();,七)DataSet表的表達(dá)式列,目標(biāo):在窗口上動(dòng)態(tài)顯示該學(xué)生的平均成績(jī)。 對(duì)DataSet中的students,增加計(jì)算列avggradec,其值為子表grade中g(shù)rade字段值的平均值,并動(dòng)態(tài)綁定到對(duì)應(yīng)的TextBox。 private void AddAvgGradeT

35、oStudents() if (dataSet.Tablesstudents.Columnsavggradec = null) dataSet.Tablesstudents.Columns.Add(avggradec); dataSet.Tablesstudents.Columnsavggradec.Expression =avg(child.grade); textBox3.DataBindings.Add(text, dataSet, students.avggradec); 在LoadData最后加AddAvgGradeToStudents() 設(shè)置textBox3為readonly。

36、修改成績(jī),平均成績(jī)即刻更新。,DataColumn.Expresion,獲取或設(shè)置表達(dá)式,用于篩選行、計(jì)算列中的值或創(chuàng)建聚合列,假設(shè)在grade表中已增加列c。 計(jì)算列: dataSet.Tablesgrade.Columns c.Expression= grade*0.9; 聚合列:支持sum、max、min和count等聚合函數(shù),見(jiàn)上例。 為篩選器指定表達(dá)式:值為true/false。 dataSet.Tablesgrade.Columnsc.Expression= subid=sub001;,Expression中對(duì)父表或子表關(guān)系引用,通過(guò)在列名稱前面加 Parent,就可以在表達(dá)式中引

37、用父表。例如,Parent.Price 引用父表的名為 Price 的列。 通過(guò)在列名稱前面加一個(gè) Child,就可以在表達(dá)式中引用子表中的列。因?yàn)樽雨P(guān)系可以返回多行,所以必須在聚合函數(shù)中包括對(duì)子列的引用。例如,Sum(Child.Price) 將返回子表中名為 Price 的列的總和。 如果某個(gè)表有多個(gè)子表,則語(yǔ)法是:Child(RelationName)。例如,如果某個(gè)表有兩個(gè)子表,它們的名稱分別為 Customers 和 Orders,則 DataRelation對(duì)象被命名為 Customers2Orders,引用將為:Avg(Child(Customers2Orders).Quanti

38、ty),八)使用Tag屬性綁定列,目標(biāo):使用RadioButton選擇性別,但Students.sex類型為bit,0表示男,1表示女。 需要在一個(gè)GroupBox中放兩個(gè)RadioButton,其Text分別為“男”和“女”,而實(shí)際只需要獲得一個(gè)RadioButton的Checked狀態(tài)就能確定性別。 由于值不同,所以不能使用RadioButton的Text屬性和students.sex綁定,可用Tag屬性與其綁定。這樣的設(shè)置必須完成兩部分工作: Tag值改變時(shí)(瀏覽時(shí))要對(duì)RadioButton的狀態(tài)作相應(yīng)改變 RadioButton狀態(tài)改變時(shí)要改變Tag值,RadioButton狀態(tài)改變

39、時(shí)改變Tag值,在RadioButton的CheckedChanged事件中實(shí)現(xiàn): if (radioButton1.Checked) radioButton1.Tag = false; else radioButton1.Tag = true; Students的sex屬性類型為bit,其值只能取0和1,與radioButton1.Tag綁定后,Tag的值為true和false。,Tag值改變時(shí)要對(duì)RadioButton的狀態(tài)作相應(yīng)改變:,首先實(shí)現(xiàn)下列方法: private void SetSexRadioButton(object sender, EventArgs e) if (radi

40、oButton1.Tag.ToString() = ) radioButton1.Checked = false; radioButton2.Checked = false; return; if (radioButton1.Tag.ToString() = False) radioButton1.Checked = true; radioButton2.Checked = false; else radioButton1.Checked = false; radioButton2.Checked = true; ,何時(shí)調(diào)用該方法:,方案一:在窗口打開(kāi)后(Load事件)及按瀏覽按鈕時(shí),調(diào)用5次

41、。 方案二:在窗口打開(kāi)后(Load事件)和this.BindingContextdataSet, “students”對(duì)象的PositionChanged事件中調(diào)用,調(diào)用2次。 在BindingControls最后加: radioButton1.DataBindings.Add(tag, dataSet, students.sex); this.BindingContextdataSet, students.PositionChanged += SetSexRadioButton; 在Form的Load事件中加: SetSexRadioButton(this, null);,九)使用程序?qū)a

42、taSet中數(shù)據(jù)表的插入、刪除、修改和檢索。,以上對(duì)dataSet的數(shù)據(jù)表的操作是通過(guò)綁定來(lái)實(shí)現(xiàn)的,修改控件中數(shù)據(jù)則自動(dòng)更新數(shù)據(jù)表中數(shù)據(jù),插入和刪除則是通過(guò)this.BindingContextdataSet, “students”的AddNew方法和RemoveAt方法實(shí)現(xiàn)。 直接對(duì)DataSet中數(shù)據(jù)表操作方法如下: 修改:dataSet.Tablesstudents.Rows0name = zhp; 插入:dataSet.Tablesstudents.Rows.InsertAt(DataRow row,int pos) 刪除:dataSet.Tablesstudents.Rows.Rem

43、oveAt(int pos),檢索:,DataSet中的Table提供了下列兩種方法檢索符合條件的行,返回符合條件的行。 Select方法: DataRow dataRow = dataSet.Tablesstudents.Select(id= + textBox4.Text + );/使用dataRow.GetLength(0)獲得符合條件的行數(shù) Find方法:檢索主鍵值,必須先建立主鍵,見(jiàn)下例。 DataRow dataRow = dataSet.Tables“students”.Rows.Find(textBox1.Text);/找不到返回null 方法比較:Select檢索條件任意,可

44、返回多行,F(xiàn)ind方法只能對(duì)建立的主鍵值檢索,返回最多一行,由于表總關(guān)于主鍵排序,所以檢索速度較select快很多。,檢索實(shí)例:,目標(biāo):輸入學(xué)生編號(hào),按“檢索”按鈕后若該學(xué)生不存在,則提示,若存在,則顯示該學(xué)生信息: 分析:定位控件顯示的行的唯一方法是設(shè)置Binding Context的Position屬性,而Find和Select返回的是dataRow,余下的問(wèn)題是如何由已知行dataRow獲得該行在table中的行序號(hào),.Net提供了該方法: dataSet.Tablesstudents.Rows.IndexOf(dataRow); 以下使對(duì)學(xué)生編號(hào)檢索的程序:,private void

45、button13_Click(object sender, EventArgs e) int idx; DataColumn dataColumn; dataColumn = new DataColumn1; dataColumn0 = dataSet.Tablesstudents.Columnsid; dataSet.Tables“students”.PrimaryKey = dataColumn; /至此為設(shè)置主鍵 DataRow dataRow=dataSet.Tablesstudents.Rows.Find(textBox4.Text); if (dataRow = null) Mes

46、sageBox.Show(沒(méi)有發(fā)現(xiàn)符合條件的行!); else idx=dataSet.Tablesstudents.Rows.IndexOf(dataRow); this.BindingContextdataSet, students.Position = idx; ,1.2.2 可視化設(shè)計(jì),構(gòu)造DataSet:前面的設(shè)計(jì)方式,必須在程序運(yùn)行后,才能確定DataSet的結(jié)構(gòu)(包含哪些Table和Relation等),.Net可以使用XML文件構(gòu)建DataSet類,這使程序設(shè)計(jì)和運(yùn)行可不依賴于和數(shù)據(jù)庫(kù)的連接,并且使數(shù)據(jù)庫(kù)結(jié)構(gòu)修改后,只要修改對(duì)應(yīng)的XML文件,而不必修改程序。 類型化DataSe

47、t和非類型化DataSet:前者在程序設(shè)計(jì)時(shí)定義(可編寫或生成)DataSet類的內(nèi)部結(jié)構(gòu),編譯時(shí)進(jìn)行類型檢查,所以類型安全,后者則在程序運(yùn)行時(shí)產(chǎn)生DataSet對(duì)象的內(nèi)部結(jié)構(gòu)(1.2.1中例子的方式),可能由于數(shù)據(jù)類型不一致而使運(yùn)行時(shí)更容易發(fā)生錯(cuò)誤。,設(shè)計(jì)步驟:,根據(jù)數(shù)據(jù)庫(kù)中表結(jié)構(gòu)生成DataSet1.XSD文件:使用菜單Add New Item/ DataSet進(jìn)入可視化地構(gòu)建DataSet模式(schema),可把Server Explorer中數(shù)據(jù)表拖入及使用工具欄中的Relation建立數(shù)據(jù)表之間的聯(lián)系,然后保存(XML格式)。 依據(jù)上面生成的XSD文件產(chǎn)生DataSet類和對(duì)象定義

48、:在Form中加入工具欄中DataSet,選擇Typed dataset。Name選擇examplea1. DataSet1(即對(duì)應(yīng)上面XSD文件),系統(tǒng)根據(jù)XSD文件內(nèi)容在dataSet11. Designer. cs文件中產(chǎn)生類定義DataSet1,并在Form1.Designer. cs中定義了該類的對(duì)象dataset11。 通過(guò)設(shè)置控件的DataBindings屬性(可選dataset11數(shù)據(jù)項(xiàng))實(shí)施綁定等設(shè)置,對(duì)應(yīng)程序也在Form1.Desig ner. cs文件中生成。,兩種類型DataSet數(shù)據(jù)的訪問(wèn)的區(qū)別:,非類型化DataSet(弱類型DataSet) dataSet.Tab

49、les“students”.Columns“id”或 dataSet.Tables0.Columns0 類型化DataSet(強(qiáng)類型DataSet) dataSet.students.idColumn,1.2.3 報(bào)表設(shè)計(jì):CrystalReport,基本原理: 使用報(bào)表設(shè)計(jì)器設(shè)計(jì)報(bào)表,設(shè)計(jì)內(nèi)容存入特殊格式的CrystalReport.rpt文件中,該報(bào)表文件也可供其他語(yǔ)言(C+或VB)開(kāi)發(fā)的程序使用。 同時(shí)生成了一個(gè)繼承于ReportClass的報(bào)表類定義文件CrystalReport.cs,其中包含了該類與rpt文件的關(guān)聯(lián),用戶通過(guò)該類實(shí)現(xiàn)對(duì)上述設(shè)計(jì)報(bào)表的操作。在該類定義文件中可以加入工具

50、箱中的組件(把組件拖入CrystalReport.csDesigner頁(yè)面)。 報(bào)表通過(guò)可視化控件CrystalReportViewer顯示。用戶只要實(shí)例化一個(gè)報(bào)表類對(duì)象,并把包含數(shù)據(jù)的DataSet對(duì)象傳給它,由報(bào)表類完成對(duì)rpt文件的解析,獲取數(shù)據(jù)并在CrystalReportViewer中顯示報(bào)表。,報(bào)表的數(shù)據(jù)來(lái)源-用非類型化DataSet產(chǎn)生XSD,使用CrystalReport,在設(shè)計(jì)階段必須確定報(bào)表的數(shù)據(jù)來(lái)源,即必須構(gòu)建DataSet框架,報(bào)表設(shè)計(jì)時(shí)各數(shù)據(jù)項(xiàng)可選自構(gòu)建好的DataSet。 在程序運(yùn)行時(shí),通過(guò)報(bào)表類的SetDataSource方法把實(shí)例化的DataSet(包含數(shù)據(jù)的)

51、對(duì)象傳遞給報(bào)表,該DataSet必須包含報(bào)表設(shè)計(jì)時(shí)所用到數(shù)據(jù)項(xiàng),或保證兩者數(shù)據(jù)模型完全一致。 由于本例DataSet為非類型化,可使用下列語(yǔ)句把DataSet模型輸出到XSD文件,供報(bào)表設(shè)計(jì)用: dataSet.WriteXmlSchema(dataset1.xsd);,一)設(shè)計(jì)List報(bào)表:學(xué)生基本信息表(CryStalReport1),構(gòu)建報(bào)表數(shù)據(jù)源: 在項(xiàng)目中加入DataSet1.XSD:在Solution Explorer中右擊項(xiàng)目名,選擇Add/Existing Item,選擇前面生成DataSet1.XSD文件。 系統(tǒng)會(huì)生成DataSet1.Designer.cs,其中定義了名為N

52、ewDataSet類,該類為依據(jù)XSD文件構(gòu)造的類型化DataSet類,報(bào)表設(shè)計(jì)時(shí)可由此獲得數(shù)據(jù)項(xiàng) 新建報(bào)表:選擇菜單Project/Add New Item,選Reporting /CrystalReport。 1)簡(jiǎn)要介紹Report Wizard: 選擇Using the Report Wizard:以下是Wizard各步: 在Project Data/ADO.NET DataSets/examplea1. DataSet1中選擇報(bào)表數(shù)據(jù)相關(guān)的表 維護(hù)表之間關(guān)系:對(duì)DataSet1中定義的表間關(guān)系進(jìn)行刪除,或根據(jù)列名(name)或主鍵自動(dòng)建立表間關(guān)系。 選擇報(bào)表中要輸出的列:,選擇分組信

53、息: 選擇統(tǒng)計(jì)信息: 分組排序: 報(bào)表中是否要包含圖表 過(guò)濾條件 報(bào)表的風(fēng)格:table含有表格線 2)從空白報(bào)表開(kāi)始設(shè)計(jì):選擇As a Blank Report 出現(xiàn)一個(gè)空白報(bào)表,有5個(gè)部分組成,分別是Report Header、Page Header、Details、Report Footer和Page Footer。 Report Header和Footer只出現(xiàn)在報(bào)表頭一頁(yè)和最后一頁(yè),Page Header和Footer出現(xiàn)在每一頁(yè)上,Details為報(bào)表的主體-數(shù)據(jù)部分。 (1)加入要使用的數(shù)據(jù)項(xiàng):右擊報(bào)表,選擇Field Explorer,在打開(kāi)的窗口中右擊DataBase Fie

54、lds選擇DataBase Expert,出現(xiàn)的對(duì)話框的Data頁(yè)框中可選擇Available Data Sources,其中列出了Project Data/ ADO.NET DataSets/examplea1.NewDataSet中的所有數(shù)據(jù)表,把它們?nèi)考尤隨elected Tables。在Link頁(yè)框中,以圖形方式顯示了被選中表在NewDataSet所包含的表間關(guān)系,可增加通過(guò)classid列建立的Students和classes表的關(guān)聯(lián)。,(2)設(shè)置Page Head:,在工具欄選擇Text Object,放入Page Header。 右擊該Text Object,選擇Edit Te

55、xt Object,輸入“學(xué)生基本信息表” 右擊該Text Object,選擇Format Object,設(shè)置其字體和對(duì)齊方式 在Field Explorer中的Special Fields,選擇Print Date,并把它拖到上述的標(biāo)題下。,(3)設(shè)置Details,把Field Explorer中students的id、name、sex和Height和classes的name拖入Details中。 編輯Page Header中自動(dòng)產(chǎn)生的Text Object,輸入對(duì)應(yīng)中文,使用Format Object設(shè)置對(duì)齊方式為居中。 右擊報(bào)表,選擇Preview Report,可預(yù)覽報(bào)表,由于報(bào)表設(shè)

56、計(jì)不需要連接數(shù)據(jù)庫(kù),所以數(shù)據(jù)為根據(jù)類型自動(dòng)生成的模擬數(shù)據(jù)。 調(diào)整數(shù)據(jù)項(xiàng)位置、尺稱、字體、對(duì)齊方式等 使用工具欄中的Box Object和Line Object為表格加上線框,線和框可跨越報(bào)表的不同區(qū)域。,(4)使用Formula Field:性別輸出,數(shù)據(jù)表中性別為bit類型,輸出為True和fase,要求輸出“男”,女。 在Field Explorer中右擊Formula Fields,選New,輸入Name為SexText,然后按“Use Expert”,進(jìn)入Formula Editor。 通過(guò)選擇Report Fields、Functions和Operators或輸入 if(studen

57、ts.sex=true) then 女 else 男 在報(bào)表中刪除Sex,然后加上SexText。,(5)分組統(tǒng)計(jì):總平均身高和分組平均身高,插入總平均身高:右擊報(bào)表,選擇Insert/Summary,選擇統(tǒng)計(jì)字段Height和統(tǒng)計(jì)函數(shù)average,統(tǒng)計(jì)字段自動(dòng)被安排在Report Footer的Height列下。 班級(jí)分組平均身高: 在報(bào)表中插入分組塊:右擊報(bào)表,選擇Insert/Group,選擇依據(jù)哪個(gè)列值分組(選classes.classid)及對(duì)該列值排序方式(升/降),確認(rèn)后報(bào)表上出現(xiàn)GroupHeaderSection1和Group FooterSection1,并在GroupH

58、eaderSection1中出現(xiàn)字段Group #1 Name,刪除它,為避免在每組開(kāi)始時(shí)顯示一個(gè)空行,右擊該灰色條帶選擇Hide,則該塊內(nèi)容不輸出。 在分組塊中插入分組的平均身高:操作基本同插入總平均身高的操作,但Summary location選擇Group #1。確認(rèn)后統(tǒng)計(jì)字段被自動(dòng)安排在GroupFootSection1中的Height列下。,分組修改:,右擊GroupHeaderSection1的灰色條帶,選擇Group Expert,可以對(duì)分組進(jìn)行增加、刪除和修改。(要?jiǎng)h除Group Header Section必須先在Group Expert中移除對(duì)應(yīng)分組) 可以對(duì)每個(gè)班級(jí)分組中再對(duì)性別分組,分別統(tǒng)計(jì)班級(jí)男同學(xué)和女同學(xué)的平均身高。 第二個(gè)分組一定是在第一個(gè)分組下的分組,不可能同時(shí)存在兩個(gè)并列的分組,就如同不可能存在兩個(gè)并列的排序一樣。,(6)排序和過(guò)濾:每個(gè)分組要求按姓名排序。,右擊報(bào)表 選擇Report/Record Sort Expert,其中已經(jīng)存在按分組1和分組2的排序(分組必須排序),把加入Sort Fields。 選擇Report/Selection Formula/Record或Group對(duì)行或分組加入過(guò)濾條件。,二)報(bào)表的預(yù)覽和打印

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論