版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第十章 数据库应用程序开发ADO.Net程序实现典型的数据库应用程序开发。l数据库连接l数据加载l数据的简单和复杂绑定l对DataSet数据浏览、插入、删除、确认和取消lDataSet的表达式列和数据检索lDataSet中数据表的关联l对数据库的更新:CommandBuilder的更新机制报表设计-CrystalReportSQL Server基本数据准备:建立数据库teaching建立下列数据表: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实现对数据表students、subjects和grade编辑和浏览功能examplea1程序设计的两种方式自编程序设计方式:自编程序实例化dataset等对象、设置属性、动态连接数据库、实现数据绑定、数据表关联等。可视化设计方式:设计阶段通过添加组件,设置组件属性完成数据库的连接、数据绑定以及数据表的关联等,然后由系统生成部分程序。1.2.1 自编程序方式一)把数据库中数据表数据显示在控件中1)连接数据库:teaching (SQL Server)2)数据库中数据载入DataSet:加载students3)DataSet中数据和控件的绑定:
4、id和TextBox的绑定1)连接数据库: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数据链接属性编辑,连接对应数据库并成功进行测试连接后,关闭窗口后teaching.udl中包含了连接字符串。2)数据库中数据载入DataSet:加载studentsprivate void LoadData()oleDbDataAdapter = new OleDbDataAdapter(select * from students, oleDbConnection); dataSe
6、t = new DataSet(); oleDbDataAdapter.Fill(dataSet, students);DataSet本身没有从数据库加载数据的能力,必须通过OleDbDataAdapter提供的Fill方法进行加载。在Fill过程中,若dataSet中没有students,则会自动建立,并把“select * from students”结果载入。3)DataSet中数据和控件的绑定:id和TextBox的绑定private void BindingControls() textBox1.DataBindings.Add(text, dataSet, “students.id
7、);textBox1的Text属性和dataSet中students表的id字段进行绑定。绑定的结果是textBox1的值和dataSet中students表的id值会同步变化。在Form的load事件中执行下列语句:ConnectDB();LoadData();BindingControls();二)复杂绑定:classid数据取自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和数据库中数据表一样,没有行顺序的概念,所有没有提供行号定位的方法和属性当一个数据表数据绑定在F
9、orm上的若干控件后,由其BindingContext成员管理从Control类继承的任意对象的 BindingManagerBase对象集合,通过设置其属性Position来控制当前显示的行:this.BindingContextdataSet, students.Position += 1;注意students和控件的绑定方式不能写成下列形式,这将使Form仅显示首行内容,而无法通过上述方式定位到其他行。(一致性)textBox1.DataBindings.Add(text, dataSet.Tablesstudents, id);首行对应Position=0,当Position=0,再-
10、1属性值将不变。当Position=总行数-1,再加1同样值不变。四)使用绑定对DataSet数据表进行插入删除插入: this.BindingContextdataSet, students.EndCurrentEdit();this.BindingContextdataSet, students.AddNew();界面显示新增的空行,如绑定的界面控件不允许空值,则界面仍显示原行内容,解决方法是为dataset中该表的列设置缺省值,例如:dataSet.Tables“account”.Columns“happendate”.DefaultValue = DateTime.Today;删除:t
11、his.BindingContextdataSet, students.RemoveAt(this.BindingContextdataSet, students.Position);取消当前行的修改:this.BindingContextdataSet, students.CancelCurrentEdit();五)通过控件输入的DataSet数据的取消和确认功能控件输入数据与DataSet数据同步:this.BindingContextdataSet, “students”.Position值变化或调用this.BindingContextdataSet, “students”.EndCu
12、rrentEdit()后,界面控件数据才写入DataSet。取消修改:dataSet.RejectChanges():取消dataSet创建或调用dataSet.AcceptChanges()以后对dataSet所作的修改。接收修改: dataSet.AcceptChanges():接收对dataSet中数据所做的修改。dataSet中各表及表中各行对象均有取消和接受修改的上述两个方法,区别是其作用的对象范围不同。六)把DataSet数据存入数据库更新数据库中数据表的唯一途径是执行SQL的insert、update或delete语句,dataSet中数据的修改(表的增、删、改),要反映到数据库
13、中,必须根据修改情况产生并执行相应的SQL语句。所以要根据对DataSet数据表的修改更新对应数据库中的数据表,必须完成下列三部分工作:l标记DataSet中数据表做过修改的所有行,并记录作了何种修改(增、删、改)。l编写或生成相应的带参数的insert、delete或update语句。l对每个修改行,根据修改的种类,执行相应的更新数据库的语句。1)标记修改行及修改种类在dataSet中表的每一行对象有一个RowState属性,记录了该行是否作了修改及作了何种修改的信息:dataSet.Tablesstudents.Rows0.RowState其值可为:DataRowState.Added/M
14、odified/Deleted和Unchanged。当dataSet中表数据载入后,各行的状态为Unchanged,当对表中某行进行修改后,会根据修改类型自动改变该行的状态。在调用AcceptChanges后,对应行状态恢复到Unchanged状态。由于更新数据库的update方法是依据该状态来确定哪些行要修改和做什么修改,所以在用dataSet数据更新数据库前,不要调用用AcceptChanges。2)编写或生成相应的带参数的SQL语句(1) 使用OleDBCommandBuilder产生更新数据库的带参数的SQL语句OleDbCommandBuilder可根据oleDBDataAdapte
15、r中的Select Command中的select语句,即调用Fill方法时执行的select语句,生成带参数的update、delete或insert语句。在窗口类中增加成员:OleDbCommandBuilder oleDbCommandBuilder; 在LoadData加载(Fill)students数据语句后加:oleDbCommandBuilder = new OleDbCommandBuilder(oleDbDataAdapter);实例化实例化oleDbCommandBuilder,并把并把oleDbDataAdapter作为其属性作为其属性DataAdapter值,在要生成值
16、,在要生成SQL语句前,语句前, oleDbCommandBuilder必必须能访问非空的须能访问非空的oleDbDataAdapter.SelectCommand。在生成在生成SQL语句前,首先会执行上述的语句前,首先会执行上述的select语句,以获得对应表的语句,以获得对应表的列名信息,为生成做准备。列名信息,为生成做准备。生成的生成的SQL语句将存放在该类的基类对应的三个语句将存放在该类的基类对应的三个private属性中:它们属性中:它们是是UpdateCommand、DeleteCommand和和InsertCommand。生成生成SQL语句的条件(如语句的条件(如UpdateCo
17、mmand)l基类对应的属性为空(如基类对应的属性为空(如UpdateCommand=null)ldataSet对应数据表中存在对应状态的行(如存在对应数据表中存在对应状态的行(如存在Modified状状态的行)态的行)在下列调用中会调用在下列调用中会调用oleDbCommandBuilder中生成中生成SQL语句的程序(并非在初始化的时候):语句的程序(并非在初始化的时候):l调用其方法调用其方法GetUpdateCommand或或GetDeleteCommand或或GetInsertCommand时,返回对应的命令串时,返回对应的命令串。l调用其属性调用其属性DataAdapter值对象值
18、对象oleDbDataAdapter所包含的所包含的方法:方法:oleDbDataAdapter.Update(dataSet, “students”);该该语句用生成的语句用生成的SQL语句及语句及dataSet修改过的数据更新数据表。修改过的数据更新数据表。比较特别是比较特别是oleDbDataAdapter是是oleDbCommandBuilder的的DataAdapter属性值,其方法却要调用拥有它的对象方法以生属性值,其方法却要调用拥有它的对象方法以生成成SQL语句,这种调用方法见语句,这种调用方法见“3)更新数据库)更新数据库”后的例。后的例。生成带参数的生成带参数的SQL语句条件
19、和时机:语句条件和时机:加入生成SQL语句的语句: 在LoadData中实例化oleDbCommndBuilder后调用下列语句以生成带参数的更新数据库的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时发现oleDbCommandBuilder中已存在这些语句,就不会再生成关于classes的更新语句。OleDbCommandBuilder其他说明:由上可知,SQL语句一但生成,改变oleDbDataAdapter的SelectCommand属性,由于生成SQL语句的第一个条件不满足,不会改变oldDbCommandBuilder
21、中已生成的SQL语句。oleDbCommandBuilder.RefreshSchema()可用于清空生成的SQL语句(基类属性),可使生成SQL语句的第一个条件满足。使用OleDbCommandBuilder的限制:select语句必须为单表的查询,包含主键,但不包含只读列(如计算列)。为了生成 INSERT、UPDATE 或 DELETE 语句,OleDbCommandBuilder 会自动使用 SelectCommand 属性来检索所需的元数据集,以获得如列名等信息,所以会降低执行效率。 (2)编写更新数据库的SQL如果Fill一个DataSet数据表对应的select语句牵涉多个表,就
22、不能使用oleDbCommandBuilder生成更新数据库的SQL语句,必须手工编写。目标:在Form的下方用DataGrid显示当前学生的各门课的名称及成绩,可以修改成绩但不能添加和删除,点击保存按钮后保存修改内容。增加下列Form类成员:private DataRelation dataRelation; /students和grade的关联private OleDbDataAdapter oleDbDataAdapter1;/用于grade表把grade数据加载到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中产生中产生grade表表/update时调用的时调用的update语句,其中语句,其中“?”表示定位参数(非命名参数),依次表示定位参数(非命名参数),依次和和/下
24、面下面oleDbDataAdapter1.UpdateCommand.Parameters中的参数对应。中的参数对应。oleDbDataAdapter1.UpdateCommand = new OleDbCommand(update grade set grade=? where id=? and subid=?,oleDbConnection);/以下语句定义执行以下语句定义执行update时三个参数来自时三个参数来自dataSet.grade(由(由fill语句第二个参语句第二个参数确定)表的哪个列数确定)表的哪个列 /定义第一个参数:名为定义第一个参数:名为“grade”,对定位参数,参
25、数按次序对应,名称无用对定位参数,参数按次序对应,名称无用OleDbParameter gradeParameter = new OleDbParameter(grade, OleDbType.Integer);/该参数数据来源该参数数据来源grade列列 gradeParameter.SourceColumn = “grade”;/数据取修改后数据,此语句可省略数据取修改后数据,此语句可省略 gradeParameter.SourceVersion = DataRowVersion.Current;/缺省缺省/定义第二个参数定义第二个参数id:数据取修改前数据数据取修改前数据OleDbPar
26、ameter idParameter = new OleDbParameter(id, OleDbType.Char,6);idParameter.SourceColumn = “id”; /数据来源于数据来源于id列列idParameter.SourceVersion = DataRowVersion.Original;/定义第三个参数定义第三个参数subid:数据取修改前数据,同时指定数据来源于数据取修改前数据,同时指定数据来源于subid列列OleDbParameter subidParameter = new OleDbParameter(subid, OleDbType.Char,
27、6,subid);subidParameter.SourceVersion = DataRowVersion.Original;/将三个参数依次加入参数表,作为将三个参数依次加入参数表,作为update语句中的三个参数语句中的三个参数oleDbDataAdapter1.UpdateCommand.Parameters.Add(gradeParameter);oleDbDataAdapter1.UpdateCommand.Parameters.Add(idParameter);oleDbDataAdapter1.UpdateCommand.Parameters.Add(subidParamete
28、r);/建立名为建立名为students_grade的两表关系,联结条件的两表关系,联结条件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)更新数据库使用下列语句更新数据库使用下列语句更新数据库(保存按钮的(
33、保存按钮的click事件)事件): /确保把和确保把和dataSet中中students及及grade绑定的控件数据写入绑定的控件数据写入dataSetthis.BindingContextdataSet,“students”.EndCurrentEdit(); this.BindingContextdataSet, grade.EndCurrentEdit();oleDbDataAdapter.Update(dataSet, students);oleDbDataAdapter1.Update(dataSet,grade);Update执行流程如下:执行流程如下:l如如oleDbDataAd
34、apter关联了一个关联了一个oleDbCommandBuilder (即前(即前者为后者的一个属性,判断方法如下例者为后者的一个属性,判断方法如下例owner!=null) ,若后者尚若后者尚未生成更新数据库的未生成更新数据库的SQL语句(其基类对象相应属性为空),则生语句(其基类对象相应属性为空),则生成。成。l执行更新语句:若程序已设置执行更新语句:若程序已设置oleDbDataAdapter中的属性如中的属性如UpdateCommand中的中的update语句,则执行该语句(即由程序员编语句,则执行该语句(即由程序员编写数据库的更新语句),否则则执行写数据库的更新语句),否则则执行ol
35、dDbCommandBuilder基类基类对象属性所存储的对象属性所存储的update语句语句下页示例如何在一个对象下页示例如何在一个对象(oleDbCommandBuilder)的属性的属性值值对象对象(oleDbDataAdapter)的方法中调用拥有它的对象的方法中调用拥有它的对象( oleDbCommandBuilder )的方法(生成的方法(生成SQL的方法的方法)例:commandBuilder对象的属性值对象dataAdapter的update方法调用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; 调用示例:若没有第二个语句,即调用示例:若没有第二个语句,即dataAdapter不和不和commandBuilder关关联,仍能调用联,仍能调用update,但返回但返回null。DataAdapter dataAdapter = new DataAdapter();CommandBuilder commandBuilder = new CommandBuilder(dataAdapter);Messa
38、geBox.Show(dataAdapter.update();七)DataSet表的表达式列目标:在窗口上动态显示该学生的平均成绩。对DataSet中的students,增加计算列avggradec,其值为子表grade中grade字段值的平均值,并动态绑定到对应的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获取或设置表达式,用于筛选行、计算列中的值或创建聚合列,假设在grade表中已增加列c。计算列:dataSet.Tablesgrade.Columns c.Expression= grade*0.9;
40、聚合列:支持sum、max、min和count等聚合函数,见上例。为筛选器指定表达式:值为true/false。dataSet.Tablesgrade.Columnsc.Expression= subid=sub001;Expression中对父表或子表关系引用通过在列名称前面加 Parent,就可以在表达式中引用父表。例如,Parent.Price 引用父表的名为 Price 的列。通过在列名称前面加一个 Child,就可以在表达式中引用子表中的列。因为子关系可以返回多行,所以必须在聚合函数中包括对子列的引用。例如,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状态就能确定性别。由于值不同,所以不能使用RadioButton的Text属性和students.sex绑定,可用Tag属性与其绑定。这样的设置必须完成两部分工作:lTag值改变时(浏览时)要对RadioButton的状态作相应改变lRadioButton状态改变时要改变Tag值RadioButton状态改变时改变Tag值在RadioButton的CheckedChanged事件中实现: if (radioButton1.Checked) radioButton1.Tag = false; else radioButton1.Tag = true;Students的sex属性类型为bit,
43、其值只能取0和1,与radioButton1.Tag绑定后,Tag的值为true和false。Tag值改变时要对RadioButton的状态作相应改变:首先实现下列方法:首先实现下列方法: 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; 何时调用该方法:方案一:在窗口打开后(Load事件)及按浏览按钮时,调用5次。方案二:在窗口打开后(Load事件)和this.BindingContextdataSet, “students”对象的PositionChanged事件中调用,调用2次。l在BindingControls最后加:radioButton1.DataBindings.Add(ta
45、g, dataSet, students.sex);this.BindingContextdataSet, students.PositionChanged += SetSexRadioButton;l在Form的Load事件中加:SetSexRadioButton(this, null);九)使用程序对dataSet中数据表的插入、删除、修改和检索。以上对dataSet的数据表的操作是通过绑定来实现的,修改控件中数据则自动更新数据表中数据,插入和删除则是通过this.BindingContextdataSet, “students”的AddNew方法和RemoveAt方法实现。直接对Data
46、Set中数据表操作方法如下:修改: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无法更新数据库两者当和子表建立rela
47、tion,均会对子表的对应行作删除标记dataSet.Tables“account”.Rowspos.Delete()和 this.BindingContextdataSet, “account”.RemoveAt(pos)中Pos的区别在删除按钮的click事件中分别用下列程序:int pos = this.BindingContextdataSet, account.Position;1)dataSet.Tablesaccount.Rowspos.Delete()2)this.BindingContextdataSet, account.RemoveAt(pos)现象:假设account表
48、中共4行第一种做法:先删第3行,有效,界面上显示第4行内容,再删,无效。反之,先删第4行,有效,界面上显示第3行内容,再删,有效。第二种做法:正确。分析第一种处理错误原因:.Net的基本处理规则:l界面和数据表绑定,界面不显示已作删除标记的行l当前显示行非最后一行,对该行执行delete(),则显示下一行,当前行号不变l当前行为最后一行,对该行执行delete(),则显示上一行,当前行号-1上例删除第3行后,显示第4行,当前行仍为3,继续执行删除,还是删除第3行上例删除最后一行后,显示第3行,当前行为第3行,继续删除,则删除第3行,显示第2行这个例子说明,这样的处理,存在漏洞。数据集数据被删除
49、时与之绑定界面数据的同步变化(与通过bindingcontext删除一致)数据集中数据表某行被删,如该行正好显示在界面上,界面检测到当前行对应数据表中的状态为删除,则判断:l数据集中存在下一行,则界面上下一行成为当前显示行,当前行行号不变。l数据集中没有下一行,则界面上上一行成为当前显示行,当前行行号-1l如删除后数据表为空,结果为如何?数据库中主码为自增类型的问题问题:l数据加载到dataset后,自增列一般不需要用户设置,新增一行后,dataset中该列一般为空,保存后数据库自动产生值,然后如果马上又删除该行,此时dataset中该主码值仍为空,保存时执行delete语句时无法定位,导致错
50、误(提示为并发错误)解决方法:l在dataset中也设置该列为自动增加列,但如在保存前做多次增加和删除后,无法保证dataset中新增行的该列的值连续(可验证:增3行,删中间行,剩下两行就会跳号,而存入数据库时数据库仍会自动生成该号,为连号)l保存后从数据库重新加载所有数据l保存后从数据库加载新增行的数据,是否可行待验证l新增或删除前先提示是否保存,必须保存后才能进行新增和删除操作,确保数据库和dataset数据一致性,但变成在线式l如设计时数据库库中该列不使用自增,而在dataset中设置自增,就避免了此问题的发生。设计的重要性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中新增行的该列值和存入数据库后的该列值数据
52、的一致性。检索:DataSet中的Table提供了下列两种方法检索符合条件的行,返回符合条件的行。Select方法:DataRow dataRow = dataSet.Tablesstudents.Select(id= + textBox4.Text + );/使用dataRow.GetLength(0)获得符合条件的行数Find方法:检索主键值,必须先建立主键,见下例。DataRow dataRow = dataSet.Tables“students”.Rows.Find(textBox1.Text);/找不到返回null方法比较:Select检索条件任意,可返回多行,Find方法只能对建立
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、有发现符合条件的行!没有发现符合条件的行!); else idx=dataSet.Tablesstudents.Rows.IndexOf(dataRow); this.BindingContextdataSet, students.Position = idx; 1.2.2 可视化设计构造DataSet:前面的设计方式,必须在程序运行后,才能确定DataSet的结构(包含哪些Table和Relation等),.Net可以使用XML文件构建DataSet类,这使程序设计和运行可不依赖于和数据库的连接,并且使数据库结构修改后,只要修改对应的XML文件,而不必修改程序。类型化DataSet和非类型化
56、DataSet:前者在程序设计时定义(可编写或生成)DataSet类的内部结构,编译时进行类型检查,所以类型安全,后者则在程序运行时产生DataSet对象的内部结构(1.2.1中例子的方式),可能由于数据类型不一致而使运行时更容易发生错误。设计步骤:根据数据库中表结构生成DataSet1.XSD文件:使用菜单Add New Item/ DataSet进入可视化地构建DataSet模式(schema),可把Server Explorer中数据表拖入及使用工具栏中的Relation建立数据表之间的联系,然后保存(XML格式)。依据上面生成的XSD文件产生DataSet类和对象定义:在Form中加入
57、工具栏中DataSet,选择Typed dataset。Name选择examplea1. DataSet1(即对应上面XSD文件),系统根据XSD文件内容在dataSet11. Designer. cs文件中产生类定义DataSet1,并在Form1.Designer. cs中定义了该类的对象dataset11。通过设置控件的DataBindings属性(可选dataset11数据项)实施绑定等设置,对应程序也在Form1.Desig ner. cs文件中生成。两种类型DataSet数据的访问的区别:非类型化DataSet(弱类型DataSet)dataSet.Tables“students”
58、.Columns“id”或dataSet.Tables0.Columns0类型化DataSet(强类型DataSet)dataSet.students.idColumn1.2.3 报表设计:CrystalReport基本原理:使用报表设计器设计报表,设计内容存入特殊格式的CrystalReport.rpt文件中,该报表文件也可供其他语言(C+或VB)开发的程序使用。同时生成了一个继承于ReportClass的报表类定义文件CrystalReport.cs,其中包含了该类与rpt文件的关联,用户通过该类实现对上述设计报表的操作。在该类定义文件中可以加入工具箱中的组件(把组件拖入CrystalRe
59、port.csDesigner页面)。报表通过可视化控件CrystalReportViewer显示。用户只要实例化一个报表类对象,并把包含数据的DataSet对象传给它,由报表类完成对rpt文件的解析,获取数据并在CrystalReportViewer中显示报表。报表的数据来源-用非类型化DataSet产生XSD使用CrystalReport,在设计阶段必须确定报表的数据来源,即必须构建DataSet框架,报表设计时各数据项可选自构建好的DataSet。在程序运行时,通过报表类的SetDataSource方法把实例化的DataSet(包含数据的)对象传递给报表,该DataSet必须包含报表设计
60、时所用到数据项,或保证两者数据模型完全一致。由于本例DataSet为非类型化,可使用下列语句把DataSet模型输出到XSD文件,供报表设计用:dataSet.WriteXmlSchema(dataset1.xsd);一)设计List报表:学生基本信息表(CryStalReport1)构建报表数据源:l在项目中加入DataSet1.XSD:在Solution Explorer中右击项目名,选择Add/Existing Item,选择前面生成DataSet1.XSD文件。l系统会生成DataSet1.Designer.cs,其中定义了名为NewDataSet类,该类为依据XSD文件构造的类型化D
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 绿色建筑设计与施工关键技术研究报告
- 家园共育模式下家庭教育的实践经验
- 体育赛事策划与组织管理研究
- 现代物流与供应链管理技术探讨
- 自动化的包装设备的设计原理及应用案例
- 2025年护师类之主管护师模拟题库及答案
- 2026广西钦州市钦北区长田街道社区卫生服务中心招聘1人备考题库及1套完整答案详解
- 2026新疆兵团第一师八团医院招聘3人备考题库及完整答案详解(易错题)
- 2026广西玉林市福绵区就业中心招聘见习生1人备考题库及完整答案详解(各地真题)
- 2026江苏南通市第一人民医院第一批招聘备案制工作人员102人备考题库及参考答案详解(能力提升)
- 澳门《网络安全管理基准规范》
- 国家事业单位招聘2024中央宣传部直属单位招聘106人笔试历年参考题库典型考点附带答案详解(3卷合一)试卷2套
- 儿科患者用药过敏反应处理
- 粤语知识问答课件
- 田忌赛马整合课件
- 2025华能澜沧江水电股份有限公司校园招聘笔试参考题库附带答案详解(3卷)
- KNX智能家居系统培训资料
- 2026年河南工业职业技术学院单招职业技能考试必刷测试卷附答案
- 企业个人信息保护合规检查清单
- DB37-T 4433-2021 固定污染源废气 挥发性有机物的测定 气袋真空瓶采样-气相色谱质谱法
- 气管食管瘘麻醉管理
评论
0/150
提交评论