天天看点

华南理工大学 2015 计算机科学与工程学院 复试 之 机试 902

版权声明:本文为博主转载文章,原文网址在下面给出,如果欣赏!觉得好,给原博主回个贴就行!

原文作者:yongh701

原文地址:【C#】华南理工大学计算机考研复试题目

备注:博主是个菜鸟,这是第一篇博客,可能会在排版上面有些错误,可以直接去原网址查看。

本人是16级华工计科院统考生,在学校并没有学过C#,通过阅读原博主的一系列文章,学习了C#编程的一些基本知识,非常感谢,特转载为本人第一篇博客。

1.   当时并没有找到过多的历年复试机试题,其实在王道论坛上历年试题非常详细,计算机考研寻找资料时到王道论坛上更加方便。王道论坛

2.   学长编写的代码中在“员工表增删改查”时“修改”与“删除”时,可以加一句判断listview1是否选中的代码。

华南理工大学 2015 计算机科学与工程学院 复试 之 机试 902

3.   数据表建立时有外键约束,修改以及删除都可能违背外键约束,使程序出现异常,可在“修改”和“删除”功能的数据库操作代码上加上try{}catch{}语句(下图为修改时的语句)

华南理工大学 2015 计算机科学与工程学院 复试 之 机试 902

4.   如果textbox中输入文字过长,超过数据库中的数据长度上限也会保存,可以设置textbox的最大长度

华南理工大学 2015 计算机科学与工程学院 复试 之 机试 902

下为正式转载文章:

华南理工大学计算机考研复试,在34所408联考高校中比较特别,除去各个学校都存在的面试环节,对比于其它科目传统笔试,华南理工大学更加倾向于使用C#窗体的程序制作来进行面试复试,这与部分学校使用传统的C语言编写算法不同。华南理工大学计算机考研复试的工程量、深度堪比一个小型的软件项目。

网上一直对此资料甚小,有也是部分同学的回忆版,草草地叙述一下题目,也写写简单编程思想。并没有一份详尽的资料。这对于部分没有接触过C#窗体的同学,有点痛苦。

下面讲解如何利用C#、SQL Server2005、VS2010完成华南理工大学计算机考研复试,以最新的2015年3月份的真题为例。

首先,第一大题,10分,送分的题目:

1、创建文件夹“d:\研究生复试\[你的中文姓名]\” 例: 张三,应创建“d:\研究生复试\张三”文件夹。 所有文档和答案都放在这个文件夹中。

2、在文件夹中建立一个readme文件(.txt或.doc均可),以说明所用的软件工具。

3、设计文档,文件名为Info.doc,数据库连接说明:如用户名,密码,ODBC/JDBC等数据源配置等(数据库连接方式及配置参数)如果必要,可以说明运行方式和相关参数 如果功能不能通过运行,则给出相应的源代码。

4、在你的目录中建立SOURCE目录,系统源文件放在该目录下

5、考完后请不要关机,人离开就可以了。

答:

在做题之前,自己先检测机器有没有Visual Studio 2005/2008/2010、开始菜单,找到Microsoft SQL Server 2005这个文件夹中的SQL Server Management Studio Express,没有这里工具,马上举手,换机器。毕竟做题时间非常紧,以下的所有内容不难,对于我这样平时写程序的人来说,甚至觉得就是无聊,但是如此之多的需求,我用了远超于1个半小时完成,各位考生好自为之。

第1题,建立文件夹就不展示了,相信每一个用过计算机的同学都会,第5题自己记得别关机,相信没有考生会这么傻吧?

第4题,一会在第三大题搞C#的在一开始创建工程时候注意好路径的选择~。

第2、3题的说明文档留在最后那么的10-20分钟写,做完没做完都好,对整个工程做一个好好的总结,同时给改卷老师好好说明你做了什么,这里暂时不理会,没写完程序写毛线!

直接第二大题,数据库设计,35分

一、建立数据库,并建立以下各表 一个员工可以到多个不同公司上班。

员工关系表EMPLOYEE(员工号EmpNo,员工姓名EmpName,性别EmpSex,年龄EmpAge)

华南理工大学 2015 计算机科学与工程学院 复试 之 机试 902

工作关系表WORKS(EmpNo员工号,CmpNo公司号,Salary薪水)

华南理工大学 2015 计算机科学与工程学院 复试 之 机试 902

公司关系表COMPANY(CmpNo公司号,CmpName公司名)

华南理工大学 2015 计算机科学与工程学院 复试 之 机试 902

要求:

1、在数据库中根据上述表的定义创建上述数据库,同时需建立相应的约束关系

答:(1)首先,你在开始菜单,找到Microsoft SQL Server 2005这个文件夹中的SQL Server Management Studio Express打开它,直接使用如下图的Windows 身份验证登录。

华南理工大学 2015 计算机科学与工程学院 复试 之 机试 902

(2)之后,如下图,右击“数据库”,新建一个数据库

华南理工大学 2015 计算机科学与工程学院 复试 之 机试 902

(3)如下图,这里以新建一个SCNT(华南理工大学的英文简称)数据库为例,虽然平时做工程没有人会修改数据库路径的,直接让系统管理的,但是,现在是考试,那你就将日志、数据两个数据库文件都改到你在第1大题、第1小题,一上来就建立的文件夹。其余所有参数不改,也没时间改,点“确定”。

华南理工大学 2015 计算机科学与工程学院 复试 之 机试 902

(4)之后,我们在SCNT这个数据库中新建查询。

记得写完的Sql语句,要涂黑之后再执行。

华南理工大学 2015 计算机科学与工程学院 复试 之 机试 902

(5)执行如下的SQL语句,完成这一小题。题目设置得相当阴险。一般情况下,关系表是写在所有表的结尾,最后建立的。因为关系表中的所有数据都是来自于其它表,没有其它表的结构是建立不起来的。而改卷老师,故意将关系表摆在中间。

可以看到如下的SQL语句,必须将关系表的建立,摆在最后,这3张表才能顺利建立起来。

[sql]  view plain  copy  print ?

  1. --在数据库中根据上述表的定义创建上述数据库,同时需建立相应的约束关系  
  2. create table [EMPLOYEE](  
  3.     [EmpNo] varchar(8) not null primary key,  
  4.     [EmpName] varchar(50) not null,  
  5.     [EmpSex] varchar(2) check([EmpSex]='男' or [EmpSex]='女'),  
  6.     [EmpAge] int check([EmpAge]>0)  
  7. )  
  8. create table [COMPANY](  
  9.     [CmpNo] varchar(8) not null primary key,  
  10.     [CmpName] varchar(50) not null  
  11. )  
  12. create table [WORKS](  
  13.     [EmpNo] varchar(8) references [EMPLOYEE]([EmpNo]),  
  14.     [CmpNo] varchar(8) references [COMPANY]([CmpNo]),  
  15.     [Salary] int check([Salary]>0)  
  16. )  

这里,所有表名、字段名补上[],是为了避免,有某些表名、字段名触发系统的关键字。

同时注意,题目,需要同时建立约束关系。

因此,Sql语句最后,该有的实体完整性、参照完整性、域完整性不能漏,没有就丢分。

2、将上面的数据输入到数据库中相应的表中

这里,推荐还是用最传统的SQL语句完成,也就是复制、粘贴改改数据的事情,比用图形界面操作要快。

[sql]  view plain  copy  print ?

  1. --将上面的数据输入到数据库中相应的表中  
  2. insert into [EMPLOYEE] values('E01','张三','女',32);  
  3. insert into [EMPLOYEE] values('E02','李四','男',28);  
  4. insert into [EMPLOYEE] values('E03','王五','女',42);  
  5. insert into [EMPLOYEE] values('E04','赵六','男',37);  
  6. insert into [EMPLOYEE] values('E05','陈七','男',51);  
  7. insert into [COMPANY] values('C01','阳光科技');  
  8. insert into [COMPANY] values('C02','晨光科技');  
  9. insert into [COMPANY] values('C03','未来科技');  
  10. insert into [WORKS] values('E01','C01',3000);  
  11. insert into [WORKS] values('E01','C02',4000);  
  12. insert into [WORKS] values('E02','C02',5000);  
  13. insert into [WORKS] values('E02','C03',2500);  
  14. insert into [WORKS] values('E03','C01',3500);  
  15. insert into [WORKS] values('E04','C02',3000);  
  16. insert into [WORKS] values('E05','C03',2000);  

同样需要注意的是,关系表的数据最后才插入。

而且,清楚地了解该字段的数据类型,不是数字,自觉补上'',是数字,千万别有''

3、将数据库备份到你的文件夹下,命名为backupInfo

备份,也就是几分钟的事,如下图,右击要备份的数据库,选择“任务”->"备份"

删除原有的默认备份路径之后,添加自定义的路径。

华南理工大学 2015 计算机科学与工程学院 复试 之 机试 902

选好路径之后,自己写好备份文件名,注意带上后缀名,

华南理工大学 2015 计算机科学与工程学院 复试 之 机试 902

弄好点确定,即可。

华南理工大学 2015 计算机科学与工程学院 复试 之 机试 902

好,这个大题,至此做完,最好能够在15分钟之内做完。

下面进入到核心的C#编程,建议这个SQL Server Management Studio Express别关。因为按照现在市场上软件编程MVC的思想,都是在数据库先组织好查询数据->推到相应的编程语言,这里是C#窗体中->再组织好数据,打印出来,一会儿自然还要多次用到SQL Server Management Studio Express。

三、基于上述数据库,请使用sql server2005+vs2008或vs2010完成员工信息管理系统,并生成相应的可运行文件(文件名为你的名字)。

具体要求如下:

1. 要求程序与数据库能进行有效连接,并具有完善的人机交互界面, 要求有参数输入界面和执行按钮,在界面上有结果输出展现区, 要求不要把所有操作全部集中在一个菜单内。

2.完成对员工关系表的添加,删除,修改和浏览四项功能。老师的性别要求用单选按钮实现。(15分)

3.统计和查询:

(1)根据员工号或员工名查找员工所在的公司名和工资,员工号或员工名不能文本输入,要求使用下拉菜单实现,并与数据库中现有信息一致(10分)

(2)统计年龄至少为40岁员工的总工资,工资按从大到小顺序排列;与数据库中现有信息一致(10分)

(3)查询至少具有两份工作员工的姓名和其公司名。(10分)

4. 具有数据完整性校验功能,当出现数据异常和操作异常时,程序应给出清楚完整的异常提示信息。(10分)

答:

由于题目要求,上来新建C#工程就尤为注意:

打开VS2010之后,点击文件->新建->项目,出现如下对话框,在左方的语言栏,请先找到C#编程语言,有可能藏在“其它语言”中,之后选择C#旗下的Windows。

在选择“Windows窗体应用程序”的时候,注意,是否有.NET版本的选择,如果有,这个.NET选择2.0。不选,如果有.net4.x也可以,编程写法也一样的,程序运行起来卡而已。

华南理工大学 2015 计算机科学与工程学院 复试 之 机试 902

最后,最最最关键的是,就算你代码不会写,也要做好的是,选择好,工程的位置就是你第一题目建立的文件夹下的Source,名称,按照题目要求,就是你的真实名称。

之后解决方案的名称,在你填完 名称 就自动完成填写,点击“确定”之后,就可以正式开始编程。

1、在正式的窗体开发之前,我们先如下图,在解决方案中,新建两个类.cs,磨刀不误砍柴工,

华南理工大学 2015 计算机科学与工程学院 复试 之 机试 902

一个是用户数据库连接、查询的DB.cs,这个类的具体作用在《【C#】利用C#窗体与SQL Server的连接、Treeview制作SQL Server数据库查看器》(点击打开链接)我已经写过了,这里不再复制、粘贴一次了,有兴趣可以去看看,具体代码如下:

[csharp]  view plain  copy  print ?

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Text;  
  4. using System.Data;//DataTable用到    
  5. using System.Data.SqlClient;//一系列的数据库操作类用到    
  6. namespace SCUT  
  7. {  
  8.     class DB : IDisposable  
  9.     {  
  10.         private SqlConnection sqlConnection;  
  11.         public DB()//私有无参构造函数    
  12.         {  
  13.             sqlConnection = new SqlConnection(@"server=.\SQLEXPRESS;database=SCNT;Trusted_Connection=SSPI;");  
  14.             sqlConnection.Open();  
  15.         }  
  16.         public DataTable getBySql(string sql)  
  17.         {//查询    
  18.             SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(new SqlCommand(sql, sqlConnection));  
  19.             DataTable dataTable = new DataTable();  
  20.             sqlDataAdapter.Fill(dataTable);  
  21.             return dataTable;  
  22.         }  
  23.         public void setBySql(string sql)  
  24.         { //修改    
  25.             new SqlCommand(sql, sqlConnection).ExecuteNonQuery();  
  26.         }  
  27.         public void Dispose()  
  28.         {//相当于析构函数    
  29.             sqlConnection.Close();  
  30.             //在C#中关闭数据库连接不能在类的析构函数中关,否则会抛“内部 .Net Framework 数据提供程序错误 1”的异常    
  31.             //通过实现C#中IDisposable接口中的Dispose()方法主要用途是释放非托管资源。    
  32.         }  
  33.     }  
  34. }  

这个类,直接使用《【C#】使用Windows身份验证连接Sql Server,ListView随窗体大小的变化而调节列宽》( 点击打开链接 )中介绍的不安全,但开发快速的Windows身份验证,去连接数据库,为了是不用像《【SQL Server】用户的设置与授权、sa用户登录、查询一个数据库中有多少张表》( 点击打开链接 ),再去SQL Server中开用户。

同时,去掉了这个类单例化的部分,单例主要作用是保证数据库连接只有一个,不会出现多次连接导致数据库的拥堵,这里题目没要求,不这样写,省些代码,感兴趣的,可以到《【php】利用单例模式设计数据库连接Model类》(点击打开链接)了解。

最后,还去掉set、getBySql中对于Sql注入过滤的部分,这些题目都没要求,不做,省时间,反正就算在实际开发怎么不及格,考试高分就行。

自己知道这是为了考试快速答题,但不符合实际开发就可以了。没必要纠结。

之后,我们再搞一个便于窗体之间与窗体之间传递数据的Intent.cs,具体代码如下,这在《【C#】窗体间互相传值》(点击打开链接)说过了,这里不再赘述。就一个存数据的字典容器。

[csharp]  view plain  copy  print ?

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Text;  
  4. namespace SCUT  
  5. {  
  6.     class Intent  
  7.     {  
  8.         public static Dictionary<string, Object> dict = new Dictionary<string, Object>();  
  9.     }  
  10. }  

上述两个工具性的cs类做完之后,可以正式开始窗体的编写。Form1.cs的布局、要修改的属性、添加的事件如下:

华南理工大学 2015 计算机科学与工程学院 复试 之 机试 902

对于C#控件毫无概念的同学,可以参考《【C#】简单窗体程序,判断是否闰年,禁止窗体调整大小,关闭窗体前的判断 》(点击打开链接)

这里摆了一个TabControl,具体可以看《【C#】标签页》(点击打开链接),完成题目1,不要将所有功能摆在一个窗体的要求。

因为接下来要完成4个功能,如下图,右击这个TabControl,为其添加到4个选项卡

华南理工大学 2015 计算机科学与工程学院 复试 之 机试 902

在TabControl中的第一个选项卡摆了一个listview,修改的属性如下图所示,listview的具体使用,请看《【C#】ListView的使用,对Access数据库的增删改查》(点击打开链接)

华南理工大学 2015 计算机科学与工程学院 复试 之 机试 902

之后,第2个标签页的布局如下:

华南理工大学 2015 计算机科学与工程学院 复试 之 机试 902

这里应题目的要求,要使用下拉菜单combobox,这个组件在《【C#】文件选择对话框OpenFileDialog与下列列表ComboBox》(点击打开链接)说过了,这里不再赘述,注意,将其的DropDownStyle,改成不能编辑的DropDownList。

之后,第三个、第四个标签页的布局内容如下,这两页的布局、所修改的属性内容基本相同,都是一个label加listview,因为,题目只是要求将查询结果打印到窗体上来。

不过,精华在最后的SQL查询代码~

华南理工大学 2015 计算机科学与工程学院 复试 之 机试 902
华南理工大学 2015 计算机科学与工程学院 复试 之 机试 902

接下来,为了完成第2题对员工表的增删改查。我们要新建一个窗体Form2,基本的流程同《【C#】窗体间互相传值》(点击打开链接),其布局、要修改的属性、添加的事件如下图所示:

华南理工大学 2015 计算机科学与工程学院 复试 之 机试 902

这里唯一注意的是,由于题目要求老师的性别要求用单选按钮实现。那么你只好在姓名那里,先拖一个panel1,再放上两个radiobutton,这样,两个radiobutton就自动互斥了。

接下来,双击form1.cs、form2.cs各个标签页的各个button,为各个按钮添加点击事件。

如果你的vs没有自动跳转,请按如下图的方式,进入代码编写界面。

华南理工大学 2015 计算机科学与工程学院 复试 之 机试 902

Form1.cs的代码如下:

[csharp]  view plain  copy  print ?

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.ComponentModel;  
  4. using System.Data;  
  5. using System.Drawing;  
  6. using System.Text;  
  7. using System.Windows.Forms;  
  8. using System.Text.RegularExpressions;//用到了正则表达式    
  9. namespace SCUT  
  10. {  
  11.     public partial class Form1 : Form  
  12.     {  
  13.         DB db;  
  14.         public Form1()  
  15.         {  
  16.             InitializeComponent();  
  17.             db = new DB();  
  18.         }  
  19.         private void Form1_Load(object sender, EventArgs e)  
  20.         {  
  21.             //员工表 增删改查 中“查部分”  
  22.             //生成表头  
  23.             listView1.Columns.Add("员工号", listView1.Width / 4 - 1, HorizontalAlignment.Left);  
  24.             listView1.Columns.Add("员工姓名", listView1.Width / 4 - 1, HorizontalAlignment.Left);  
  25.             listView1.Columns.Add("性别", listView1.Width / 4 - 1, HorizontalAlignment.Left);  
  26.             listView1.Columns.Add("年龄", listView1.Width / 4 - 1, HorizontalAlignment.Left);  
  27.             //表的内容  
  28.             DataTable table = db.getBySql(@"select * from [EMPLOYEE]");  
  29.             listView1.BeginUpdate();//数据更新,UI暂时挂起,直到EndUpdate绘制控件,可以有效避免闪烁并大大提高加载速度      
  30.             for (int i = 0; i < table.Rows.Count; i++)  
  31.             {  
  32.                 ListViewItem listViewItem = new ListViewItem();//生成每一列    
  33.                 for (int j = 0; j < table.Columns.Count; j++)  
  34.                 {  
  35.                     if (j <= 0)  
  36.                     {  
  37.                         listViewItem.Text = table.Rows[i][j] + "";  
  38.                     }  
  39.                     else  
  40.                     {  
  41.                         listViewItem.SubItems.Add(table.Rows[i][j] + "");  
  42.                     }  
  43.                 }  
  44.                 listView1.Items.Add(listViewItem);  
  45.             }  
  46.             listView1.EndUpdate();//结束数据处理,UI界面一次性绘制  
  47.             //查询3-1  
  48.             //加载现有的员工号  
  49.             table = db.getBySql(@"select [EmpNo] from [EMPLOYEE]");  
  50.             for (int i = 0; i < table.Rows.Count; i++)  
  51.             {  
  52.                 for (int j = 0; j < table.Columns.Count; j++)  
  53.                 {  
  54.                     comboBox1.Items.Add(table.Rows[i][j] + "");  
  55.                 }  
  56.             }  
  57.             comboBox1.SelectedIndex = 0;  
  58.             //加载现有的员工名  
  59.             table = db.getBySql(@"select [EmpName] from [EMPLOYEE]");  
  60.             for (int i = 0; i < table.Rows.Count; i++)  
  61.             {  
  62.                 for (int j = 0; j < table.Columns.Count; j++)  
  63.                 {  
  64.                     comboBox2.Items.Add(table.Rows[i][j] + "");  
  65.                 }  
  66.             }  
  67.             comboBox2.SelectedIndex = 0;  
  68.             //表3-2  
  69.             //统计年龄至少为40岁员工的总工资,工资按从大到小顺序排列  
  70.             //生成表头  
  71.             listView3.Columns.Add("员工号", listView1.Width / 5 - 1, HorizontalAlignment.Left);  
  72.             listView3.Columns.Add("员工姓名", listView1.Width / 5 - 1, HorizontalAlignment.Left);  
  73.             listView3.Columns.Add("性别", listView1.Width / 5 - 1, HorizontalAlignment.Left);  
  74.             listView3.Columns.Add("年龄", listView1.Width / 5 - 1, HorizontalAlignment.Left);  
  75.             listView3.Columns.Add("总工资", listView1.Width / 5 - 1, HorizontalAlignment.Left);  
  76.             //表的内容  
  77.             table = db.getBySql(@"select [EMPLOYEE].[EmpNo],[EMPLOYEE].[EmpName],[EMPLOYEE].[EmpSex],[EMPLOYEE].[EmpAge],sum([WORKS].[Salary]) as '总工资' " +  
  78.                 " from [EMPLOYEE],[WORKS]" +  
  79.                 " where [EMPLOYEE].[EmpAge]>=40" +  
  80.                 " and [EMPLOYEE].[EmpNo]=[WORKS].[EmpNo]" +  
  81.                 " group by [EMPLOYEE].[EmpNo],[EMPLOYEE].[EmpName],[EMPLOYEE].[EmpSex],[EMPLOYEE].[EmpAge]" +  
  82.                 " order by '总工资' desc");  
  83.             listView3.BeginUpdate();//数据更新,UI暂时挂起,直到EndUpdate绘制控件,可以有效避免闪烁并大大提高加载速度      
  84.             for (int i = 0; i < table.Rows.Count; i++)  
  85.             {  
  86.                 ListViewItem listViewItem = new ListViewItem();//生成每一列    
  87.                 for (int j = 0; j < table.Columns.Count; j++)  
  88.                 {  
  89.                     if (j <= 0)  
  90.                     {  
  91.                         listViewItem.Text = table.Rows[i][j] + "";  
  92.                     }  
  93.                     else  
  94.                     {  
  95.                         listViewItem.SubItems.Add(table.Rows[i][j] + "");  
  96.                     }  
  97.                 }  
  98.                 listView3.Items.Add(listViewItem);  
  99.             }  
  100.             listView3.EndUpdate();//结束数据处理,UI界面一次性绘制。   
  101.             //表3-3  
  102.             //查询至少具有两份工作员工的姓名和其公司名  
  103.             //生成表头  
  104.             listView4.Columns.Add("员工姓名", listView1.Width / 2 - 2, HorizontalAlignment.Left);  
  105.             listView4.Columns.Add("公司名", listView1.Width / 2 - 2, HorizontalAlignment.Left);  
  106.             //表的内容  
  107.             table = db.getBySql(@"select [EMPLOYEE].[EmpName],[COMPANY].[CmpName] from [EMPLOYEE],[COMPANY],[WORKS],(" +  
  108.             " select [EmpName],count([CmpName]) as 'CmpNum'" +  
  109.             " from [EMPLOYEE],[WORKS],[COMPANY]" +  
  110.             " where [EMPLOYEE].[EmpNo]=[WORKS].[EmpNo]" +  
  111.             " and [COMPANY].[CmpNo]=[WORKS].[CmpNo]" +  
  112.             " group by [EmpName]" +  
  113.             " having count([CmpName])>1" +  
  114.             " ) as t1" +  
  115.             " where [EMPLOYEE].[EmpNo]=[WORKS].[EmpNo]" +  
  116.             " and [COMPANY].[CmpNo]=[WORKS].[CmpNo]" +  
  117.             " and [EMPLOYEE].[EmpName]=t1.[EmpName]");  
  118.             listView4.BeginUpdate();//数据更新,UI暂时挂起,直到EndUpdate绘制控件,可以有效避免闪烁并大大提高加载速度      
  119.             for (int i = 0; i < table.Rows.Count; i++)  
  120.             {  
  121.                 ListViewItem listViewItem = new ListViewItem();//生成每一列    
  122.                 for (int j = 0; j < table.Columns.Count; j++)  
  123.                 {  
  124.                     if (j <= 0)  
  125.                     {  
  126.                         listViewItem.Text = table.Rows[i][j] + "";  
  127.                     }  
  128.                     else  
  129.                     {  
  130.                         listViewItem.SubItems.Add(table.Rows[i][j] + "");  
  131.                     }  
  132.                 }  
  133.                 listView4.Items.Add(listViewItem);  
  134.             }  
  135.             listView4.EndUpdate();//结束数据处理,UI界面一次性绘制。   
  136.         }  
  137.         private void button1_Click(object sender, EventArgs e)  
  138.         {  
  139.             Form2 form2 = new Form2();//声明要使用form2窗体      
  140.             //将form1当前的位置压入Intent中的dict      
  141.             Intent.dict["form1_text"] = this.Text;  
  142.             Intent.dict["form1_flag"] = 0;//传个flag进去代表这是“添加”    
  143.             if (form2.ShowDialog() == DialogResult.OK)  
  144.             {//这个判断,将会等到form2被关闭之后才执行,如果form2返回一个OK值   
  145.                 bool canAdd = true;  
  146.                 foreach (ListViewItem item in this.listView1.Items)  
  147.                 {  
  148.                     if (Intent.dict["form2_textbox1_text"] + "" == item.SubItems[0].Text)  
  149.                     {  
  150.                         canAdd = false;  
  151.                         MessageBox.Show("已存在该员工号!", this.Text);  
  152.                         break;  
  153.                     }  
  154.                 }  
  155.                 Regex regex = new Regex("^[0-9]*$");  
  156.                 if (!regex.IsMatch(Intent.dict["form2_textbox3_text"] + ""))//利用正则表达式判断是否输入的是数字    
  157.                 {  
  158.                     canAdd = false;  
  159.                     MessageBox.Show("年龄不为正数!", this.Text);  
  160.                 }  
  161.                 if (canAdd)  
  162.                 {  
  163.                     ListViewItem listViewItem = new ListViewItem();//在listview中添加一项    
  164.                     listViewItem.Text = Intent.dict["form2_textbox1_text"] + "";  
  165.                     listViewItem.SubItems.Add(Intent.dict["form2_textbox2_text"] + "");  
  166.                     listViewItem.SubItems.Add(Intent.dict["form2_radioButton"] + "");  
  167.                     listViewItem.SubItems.Add(Intent.dict["form2_textbox3_text"] + "");  
  168.                     listView1.Items.Add(listViewItem);  
  169.                     db.setBySql("insert into [EMPLOYEE] values('" + Intent.dict["form2_textbox1_text"] + "','" + Intent.dict["form2_textbox2_text"] + "','" + Intent.dict["form2_radioButton"] + "'," + Intent.dict["form2_textbox3_text"] + ")");  
  170.                 }  
  171.             }  
  172.         }  
  173.         private void button2_Click(object sender, EventArgs e)  
  174.         {  
  175.             Form2 form2 = new Form2();//声明要使用form2窗体      
  176.             //将form1当前的位置压入Intent中的dict      
  177.             Intent.dict["form1_text"] = this.Text;  
  178.             Intent.dict["form1_flag"] = 1;//传个flag进去代表这是“修改”    
  179.             Intent.dict["form1_selectedItems0"] = listView1.SelectedItems[0].SubItems[0].Text;  
  180.             Intent.dict["form1_selectedItems1"] = listView1.SelectedItems[0].SubItems[1].Text;  
  181.             Intent.dict["form1_selectedItems2"] = listView1.SelectedItems[0].SubItems[2].Text;  
  182.             Intent.dict["form1_selectedItems3"] = listView1.SelectedItems[0].SubItems[3].Text;  
  183.             Intent.dict["form1_flag"] = 1;//传个flag进去代表这是“修改”    
  184.             if (form2.ShowDialog() == DialogResult.OK)  
  185.             {//这个判断,将会等到form2被关闭之后才执行,如果form2返回一个OK值   
  186.                 bool canUpdate = true;  
  187.                 if (!((Intent.dict["form1_selectedItems0"] + "") == (Intent.dict["form2_textbox1_text"] + "")))//仅当用户修改过员工号才进行遍历  
  188.                 {  
  189.                     foreach (ListViewItem item in this.listView1.Items)  
  190.                     {  
  191.                         if (Intent.dict["form2_textbox1_text"] + "" == item.SubItems[0].Text)  
  192.                         {  
  193.                             canUpdate = false;  
  194.                             MessageBox.Show("已存在该员工号!", this.Text);  
  195.                             break;  
  196.                         }  
  197.                     }  
  198.                 }  
  199.                 Regex regex = new Regex("^[0-9]*$");  
  200.                 if (!regex.IsMatch(Intent.dict["form2_textbox3_text"] + ""))//利用正则表达式判断是否输入的是数字    
  201.                 {  
  202.                     canUpdate = false;  
  203.                     MessageBox.Show("年龄不为正数!", this.Text);  
  204.                 }  
  205.                 if (canUpdate)  
  206.                 {  
  207.                     ListViewItem listViewItem = new ListViewItem();//在listview中添加一项    
  208.                     listView1.SelectedItems[0].SubItems[0].Text = Intent.dict["form2_textbox1_text"] + "";  
  209.                     listView1.SelectedItems[0].SubItems[1].Text = Intent.dict["form2_textbox2_text"] + "";  
  210.                     listView1.SelectedItems[0].SubItems[2].Text = Intent.dict["form2_radioButton"] + "";  
  211.                     listView1.SelectedItems[0].SubItems[3].Text = Intent.dict["form2_textbox3_text"] + "";  
  212.                     db.setBySql("update [EMPLOYEE] set [EmpNo]='" + Intent.dict["form2_textbox1_text"] + "' where [EmpNo]='" + Intent.dict["form1_selectedItems0"] + "';");  
  213.                     db.setBySql("update [EMPLOYEE] set [EmpName]='" + Intent.dict["form2_textbox2_text"] + "' where [EmpName]='" + Intent.dict["form1_selectedItems1"] + "';");  
  214.                     db.setBySql("update [EMPLOYEE] set [EmpSex]='" + Intent.dict["form2_radioButton"] + "' where [EmpSex]='" + Intent.dict["form1_selectedItems2"] + "';");  
  215.                     db.setBySql("update [EMPLOYEE] set [EmpAge]='" + Intent.dict["form2_textbox3_text"] + "' where [EmpAge]='" + Intent.dict["form1_selectedItems3"] + "';");  
  216.                 }  
  217.             }  
  218.         }  
  219.         private void button3_Click(object sender, EventArgs e)  
  220.         {  
  221.             db.setBySql("delete from [EMPLOYEE] where [EmpNo]='" + listView1.SelectedItems[0].SubItems[0].Text + "';");  
  222.             listView1.SelectedItems[0].Remove();//删除一定要放在数据库操作之后,不然选中项再也取不到了    
  223.         }  
  224.         private void button4_Click(object sender, EventArgs e)  
  225.         {  
  226.             listView2.Clear();  
  227.             //生成表头    
  228.             listView2.Columns.Add("员工号", listView1.Width / 4 - 1, HorizontalAlignment.Left);  
  229.             listView2.Columns.Add("员工名", listView1.Width / 4 - 1, HorizontalAlignment.Left);  
  230.             listView2.Columns.Add("公司名", listView1.Width / 4 - 1, HorizontalAlignment.Left);  
  231.             listView2.Columns.Add("薪水", listView1.Width / 4 - 1, HorizontalAlignment.Left);  
  232.             //表的内容  
  233.             DataTable table = db.getBySql(@"select [EMPLOYEE].[EmpNo],[EMPLOYEE].[EmpName],[COMPANY].[CmpName],[WORKS].[Salary] from [EMPLOYEE],[COMPANY],[WORKS]" +  
  234.             " where [EMPLOYEE].[EmpNo]=[WORKS].[EmpNo]" +  
  235.             " and [COMPANY].[CmpNo]=[WORKS].[CmpNo]" +  
  236.             " and [EMPLOYEE].[EmpNo]='" + comboBox1.Text + "'");  
  237.             listView2.BeginUpdate();//数据更新,UI暂时挂起,直到EndUpdate绘制控件,可以有效避免闪烁并大大提高加载速度      
  238.             for (int i = 0; i < table.Rows.Count; i++)  
  239.             {  
  240.                 ListViewItem listViewItem = new ListViewItem();//生成每一列    
  241.                 for (int j = 0; j < table.Columns.Count; j++)  
  242.                 {  
  243.                     if (j <= 0)  
  244.                     {  
  245.                         listViewItem.Text = table.Rows[i][j] + "";  
  246.                     }  
  247.                     else  
  248.                     {  
  249.                         listViewItem.SubItems.Add(table.Rows[i][j] + "");  
  250.                     }  
  251.                 }  
  252.                 listView2.Items.Add(listViewItem);  
  253.             }  
  254.             listView2.EndUpdate();//结束数据处理,UI界面一次性绘制  
  255.         }  
  256.         private void button5_Click(object sender, EventArgs e)  
  257.         {  
  258.             listView2.Clear();  
  259.             //生成表头    
  260.             listView2.Columns.Add("员工号", listView1.Width / 4 - 1, HorizontalAlignment.Left);  
  261.             listView2.Columns.Add("员工名", listView1.Width / 4 - 1, HorizontalAlignment.Left);  
  262.             listView2.Columns.Add("公司名", listView1.Width / 4 - 1, HorizontalAlignment.Left);  
  263.             listView2.Columns.Add("薪水", listView1.Width / 4 - 1, HorizontalAlignment.Left);  
  264.             //表的内容  
  265.             DataTable table = db.getBySql(@"select [EMPLOYEE].[EmpNo],[EMPLOYEE].[EmpName],[COMPANY].[CmpName],[WORKS].[Salary] from [EMPLOYEE],[COMPANY],[WORKS]" +  
  266.             " where [EMPLOYEE].[EmpNo]=[WORKS].[EmpNo]" +  
  267.             " and [COMPANY].[CmpNo]=[WORKS].[CmpNo]" +  
  268.             " and [EMPLOYEE].[EmpName]='" + comboBox2.Text + "'");  
  269.             listView2.BeginUpdate();//数据更新,UI暂时挂起,直到EndUpdate绘制控件,可以有效避免闪烁并大大提高加载速度      
  270.             for (int i = 0; i < table.Rows.Count; i++)  
  271.             {  
  272.                 ListViewItem listViewItem = new ListViewItem();//生成每一列    
  273.                 for (int j = 0; j < table.Columns.Count; j++)  
  274.                 {  
  275.                     if (j <= 0)  
  276.                     {  
  277.                         listViewItem.Text = table.Rows[i][j] + "";  
  278.                     }  
  279.                     else  
  280.                     {  
  281.                         listViewItem.SubItems.Add(table.Rows[i][j] + "");  
  282.                     }  
  283.                 }  
  284.                 listView2.Items.Add(listViewItem);  
  285.             }  
  286.             listView2.EndUpdate();//结束数据处理,UI界面一次性绘制  
  287.         }  
  288.     }  
  289. }  

Form2.cs的代码如下:

[csharp]  view plain  copy  print ?

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.ComponentModel;  
  4. using System.Data;  
  5. using System.Drawing;  
  6. using System.Text;  
  7. using System.Windows.Forms;  
  8. namespace SCUT  
  9. {  
  10.     public partial class Form2 : Form  
  11.     {  
  12.         public Form2()  
  13.         {  
  14.             InitializeComponent();  
  15.         }  
  16.         private void Form2_Load(object sender, EventArgs e)  
  17.         {  
  18.             if ((int)Intent.dict["form1_flag"] == 0)  
  19.             {  
  20.                 this.Text = Intent.dict["form1_text"] + "";  
  21.                 textBox1.Focus();//设置焦点停留在textBox1中     
  22.             }  
  23.             else  
  24.             {  
  25.                 this.Text = Intent.dict["form1_text"] + "";  
  26.                 textBox1.Text = Intent.dict["form1_selectedItems0"] + "";  
  27.                 textBox2.Text = Intent.dict["form1_selectedItems1"] + "";  
  28.                 if (Intent.dict["form1_selectedItems2"] + "" == "男")  
  29.                 {  
  30.                     radioButton1.Checked = true;  
  31.                 }  
  32.                 else {  
  33.                     radioButton2.Checked = true;  
  34.                 }  
  35.                 textBox3.Text = Intent.dict["form1_selectedItems3"] + "";  
  36.                 textBox1.Focus();//设置焦点停留在textBox1中     
  37.                 textBox1.SelectAll();//要先有焦点才能全选    
  38.             }    
  39.         }  
  40.         private void button1_Click(object sender, EventArgs e)  
  41.         {  
  42.             if (textBox1.Text == "" || textBox2.Text == "" || textBox3.Text == "" || (!radioButton1.Checked && !radioButton2.Checked))  
  43.             {  
  44.                 MessageBox.Show("任意一项没有完成填写!", this.Text);  
  45.             }  
  46.             else  
  47.             {  
  48.                 //关闭form2之间,将要传给form1的值压入Intent中的dict      
  49.                 Intent.dict["form2_textbox1_text"] = textBox1.Text;  
  50.                 Intent.dict["form2_textbox2_text"] = textBox2.Text;  
  51.                 if (radioButton1.Checked)  
  52.                 {  
  53.                     Intent.dict["form2_radioButton"] = "男";  
  54.                 }  
  55.                 else  
  56.                 {  
  57.                     Intent.dict["form2_radioButton"] = "女";  
  58.                 }  
  59.                 Intent.dict["form2_textbox3_text"] = textBox3.Text;  
  60.                 this.DialogResult = DialogResult.OK;//同时设置返回值为OK,不设置的话,默认返回Cancel      
  61.                 this.Close();  
  62.             }  
  63.         }  
  64.         private void button2_Click(object sender, EventArgs e)  
  65.         {  
  66.             this.Close();    
  67.         }  
  68.     }  
  69. }  

在上述的代码中:

(1)对于第2题的增删改查,就是《【C#】ListView的使用,对Access数据库的增删改查》(点击打开链接)中的内容,第4大题,要保证输入的完整性校验,使用的C#的正则表达式,具体请看《【C#】利用正则表达式判断输入是否为纯数字、容器类》(点击打开链接)。

这属于C#对Sql Server操作的基础,是每一个学习C#窗体,投身C#开发程序猿的必修课。

做好之后,程序运行结果如下:

华南理工大学 2015 计算机科学与工程学院 复试 之 机试 902

(2)对于题目第3-1中,在程序一开始的Load事件,先直接将数据库员工表EMPLOYEE表中的员工号EmpNo,员工名EmpName查询出来,加载到两个Combobox中,用户点击button4或者button5,利用Combobox的Text属性获得当前Combobox选定的值。

此时,问题演变成,已知员工号、员工名查找员工所在的公司名和工资。

利用多表连接查询,其实说白了,因为属性分布于EMPLOYEE、WORKS、COMPANY三张表,就是一次性,查询EMPLOYEE、WORKS、COMPANY三张表,根据建表时的参照完整性,也就是外键,添加一个连接条件。

以下是语句:

[sql]  view plain  copy  print ?

  1. select * from EMPLOYEE,COMPANY,WORKS  
  2. where EMPLOYEE.EmpNo=WORKS.EmpNo  
  3. and COMPANY.CmpNo=WORKS.CmpNo  

的查询结果,注意上述语句,写在C#代码中,涉及换行,每行的第一个字符,一定是空格,要么每行的最后一个字符是空格。

同时,表名、字段名加上[],以免触发系统关键字产生歧义。在字符串上补上@,让此字符串所有要涉及转义的字符,自动转义。

华南理工大学 2015 计算机科学与工程学院 复试 之 机试 902

在上述查询结果中,只要取出相应的列,再补上已知的员工号或员工名,构造到C#中就好,将上述的sql语句中的*换成 某某表.某某字段,某某表.某某字段…… 的形式就好,

因此C#中的语句也就演变成:

[csharp]  view plain  copy  print ?

  1. DataTable table = db.getBySql(@"select [EMPLOYEE].[EmpNo],[EMPLOYEE].[EmpName],[COMPANY].[CmpName],[WORKS].[Salary] from [EMPLOYEE],[COMPANY],[WORKS]" +  
  2. " where [EMPLOYEE].[EmpNo]=[WORKS].[EmpNo]" +  
  3. " and [COMPANY].[CmpNo]=[WORKS].[CmpNo]" +  
  4. " and [EMPLOYEE].[EmpName]='" + comboBox2.Text + "'");  

以上是根据员工名查询的,根据员工号查询的同理。

完成之后的截图如下:

华南理工大学 2015 计算机科学与工程学院 复试 之 机试 902

(3)题目3-2中的查询,没有任何关于C#的事,核心在于SQL语句的构造,这里涉及到《【Mysql】利用group by附带having进行聚类查询》(点击打开链接)中提到过的聚类查询。

思考过程如下,同样还是从:

[sql]  view plain  copy  print ?

  1. select * from EMPLOYEE,COMPANY,WORKS  
  2. where EMPLOYEE.EmpNo=WORKS.EmpNo  
  3. and COMPANY.CmpNo=WORKS.CmpNo  

三张表联立起来的查询结果入手,

接下来,我们要将查询结果中,出现 相同的 员工号、员工姓名、性别、年龄 的行,合起来,

华南理工大学 2015 计算机科学与工程学院 复试 之 机试 902

整合过程中,对于不相同的公司号、公司名,我们舍弃,而工资,我们采取相加的形式合起来,因此,也就得到如下的查询语句:

[sql]  view plain  copy  print ?

  1. select EMPLOYEE.EmpNo as '员工号',EMPLOYEE.EmpName as '员工姓名',EMPLOYEE.EmpSex as '性别',EMPLOYEE.EmpAge as '年龄',sum(WORKS.Salary) as '总工资'   
  2. from EMPLOYEE,WORKS  
  3. where EMPLOYEE.EmpAge>=40  
  4. and EMPLOYEE.EmpNo=WORKS.EmpNo  
  5. group by EMPLOYEE.EmpNo,EMPLOYEE.EmpName,EMPLOYEE.EmpSex,EMPLOYEE.EmpAge  

查询结果如下:

华南理工大学 2015 计算机科学与工程学院 复试 之 机试 902

最后,在Form1的Load方法中,将这个查询结果的语句,后面补个order by '总工资' desc,按题目要求工资按从大到小顺序排列,再构造到C#窗体的listview3中就好,完成的结果如下:

华南理工大学 2015 计算机科学与工程学院 复试 之 机试 902

这题,相对来说,没有这么多代码量,耗时比较少,就是思想过程有点复杂,不过理解了之后就是送分的。

建议先做,分也不少,也简单。

(4)最后一题,也是差不多性质,只是构造出来的SQL语句更加复杂。

它要查询至少具有两份工作员工的姓名和其公司名,我们还是不管,先跟上题一样,我们先将索要需求的字段,查询出来的说,之后,同样聚类,只是这次聚类的方式不同,我们仅需要将查询结果中,出现 相同的 员工姓名 的行,合起来,合的过程中,行与行之间的 公司名 字段是不同,这个字段通过,计算出现次数合并,其余字段不要。

因此,Sql语句演变成如下:

[sql]  view plain  copy  print ?

  1. select EmpName,count(CmpName) as 'CmpNum'  
  2. from EMPLOYEE,WORKS,COMPANY  
  3. where EMPLOYEE.EmpNo=WORKS.EmpNo  
  4. and COMPANY.CmpNo=WORKS.CmpNo  
  5. group by EmpName  
  6. having count(CmpName)>1  

运行结果如下:

华南理工大学 2015 计算机科学与工程学院 复试 之 机试 902

这显然还不是最后的查询结果,但离查询结果已经很接近了。

只要设这个查询结果为表t1,再与固有EMPLOYEE、WORKS、COMPANY三张表连接起来查询即可,连接条件补上t1的EmpName等于EMPLOYEE的EmpName完事,

因此,最终的Sql语句演变成这个样子:

[sql]  view plain  copy  print ?

  1. select EMPLOYEE.EmpName,COMPANY.CmpName from EMPLOYEE,COMPANY,WORKS,(  
  2. select EmpName,count(CmpName) as 'CmpNum'  
  3. from EMPLOYEE,WORKS,COMPANY  
  4. where EMPLOYEE.EmpNo=WORKS.EmpNo  
  5. and COMPANY.CmpNo=WORKS.CmpNo  
  6. group by EmpName  
  7. having count(CmpName)>1  
  8. ) as t1  
  9. where EMPLOYEE.EmpNo=WORKS.EmpNo  
  10. and COMPANY.CmpNo=WORKS.CmpNo  
  11. and EMPLOYEE.EmpName=t1.EmpName  

就是一个4表连接查询而已,不过其中一个表,是我们的查询结果,最终构造的C#的listview4,结果如下:

华南理工大学 2015 计算机科学与工程学院 复试 之 机试 902

至此整个程序做完。

不过题目还没有完成,我们要回过头来完成第一题的文档。

首先,打开你C#解决方案所在的文件夹:

1、在这个文件夹中,直接打开.sln就能够重新进入源代码的编辑界面,因此你在文档中,写好打开这个文件,进入解决方案,再点击左侧的各个.cs文件,能够读到你的源代码。

华南理工大学 2015 计算机科学与工程学院 复试 之 机试 902

2、关于直接运行的exe,在SCUT(这里应该会变成你的名字)\SCUT(这里应该会变成你的名字)\bin\Debug下的.exe,这一点也是需要在文档中,给改卷老师提到的。

华南理工大学 2015 计算机科学与工程学院 复试 之 机试 902

这个文件夹只要你写程序,编译过就会自动生成。根本不用浪费时间去生成什么exe。

其实一般情况做窗体,将Debug文件夹,重命名拖给用户,让用户按装好.NET Framework 2.0,就OK

3、最后,数据库,先说明你的数据库、备份,在什么什么文件夹:

华南理工大学 2015 计算机科学与工程学院 复试 之 机试 902

然后写,数据库,直接负载于Sql Server中,不设密码,开放权限,直接通过Windows身份登录就能够查看。

如不能发现,请根据如下图的过程,将上图的mdf,附加到Sql Server中,即可。

华南理工大学 2015 计算机科学与工程学院 复试 之 机试 902

反正整个流程就是这样,当然试题、数据是每年不同的,关键是理解其中的方法。

在考试过程不能上网、就只有1.5小时,自己好好背背关键代码,好自为之。

我整个程序做下来,用的时间远多于1.5小时,因为这个软件规模实在是太大了。

当然整个过程的核心是不变了,SQL查好->C#读->C#构造数据到前台,万变不离其宗。

最后,祝各位通过考研初试,有机会到华南理工复试的计算机考生,在考研复试的过程中,没有任何意外,稳稳当当,别说做完,能够在1.5小时中,完成上述80%的内容,基本稳了。