C#基础视频教程6.2 如何简单读写数据库
上一节我们简单介绍了数据库的读写,所使用的数据库都是随便写的(用水果代替,但不是真正的食品零售数据表,至少没有价格,销量等等)。这一节我们思考如何实现一个测试题的数据库,所谓的测试题数据库就是假定系统里预存了1000道题目,每个学生考试随机抽查50题,以保证每次考试很难相互抄袭,而且每个题目设置时间限制,到时间不作答就认为放弃,考试完成自动阅卷等等,这些功能都是普通的纸质考试没法实现的。
那么首先就是数据库的设计,能够想到的试题至少包含下面的信息(题目的参考答案和当前答案是一个很难讲的问题,比如选择题有多选的情况,比如简答题没法一一对应的情况,但是为了简化起见还是应该先做成字符串,如果用户回答A,B,C三个而正确答案是AB两个,则错选0分,如果正确答案是ABCD,则漏选得一半分数,这些复杂的逻辑处理要后面慢慢优化,一开始要先把大的框架搭建好)
初步设计成两张表,一个是试题库,一个是考试记录库(可能我们需要统计有多少人参加了考试,考试的结果,每个学生的成绩之类的,表的结构不合理后面可以再修改,基本的功能应该够了)

有了数据库之后,下面一步就是录入试题(对应了数据库的增加),可以想象淘宝网如果没有卖家先把宝贝传到数据库,买家搜不到任何东西,这个网站也没有任何价值,所以数据库首先要有内容,我们要首先设计一个人机界面,给老师录入试题。注意要尽量用最适合的控件,比如编号就是数字上下的控件,试题类型就是combobox,而文本框也要做一些限制,比如只允许输入数字(可以提高软件的用户体验)

把数据库的连接做成一个标准方法,例如我们可以指定在连接的时候需要给目标数据库的路径,密码,数据表的名称(其实还可以做得更复杂,比如不带密码则密码设置为空,当检测到密码为空的时候就用不带密码的语句),注意把原来字符串替换成变量的写法,选出来之后替换成两个双引号,然后再在中间加两个空格,再在空格中加变量名,这样不容易出错,连接成功或者失败也是布尔值对外返回。

为了让代码更加整洁,对一个题目所包含的全部信息,我们都做成一个结构体(这个结构体要跟数据库对应起来),这个数据库增加方法就比较简洁,只需要传入一个自定义类型即可

在点击录入按钮的时候,首先实例化一个结构体,然后执行具体函数,为了测试方便可以随便录入几个数据(我们可以从数据库更精简的角度出发,如果问题类型保存原模原样的字符串"判断题","选择题","简答题",那么同样的一条记录会耗费更多的存储空间,所以在真正的数据库设计中都需要把每个字段设计的尽可能简洁)

把数据录入的方法也做成函数的方式,注意传入的是一个结构体类型(这个结构体就对应一条记录,以后一种数据库文件的读写对应一种结构体,也对应一种方法这样做比较好移植和修改)

数据录入其实首先要执行一个数据查询,比如你淘宝注册一个账号,上传一个宝贝,肯定有很多规则限制。账号的用户名不允许非法字符,宝贝的描述不允许有敏感字符等等。我们这里因为只是自己用,所以可以暂时不考虑这些,但是试题编号肯定要求唯一,不然就有缺陷了,没法真正排序得到从小到大的结果了(我们可能还想着1-100题都是判断题,101-200题都是选择题,出题的时候从1-100和101-200都随机出20题这样)

有了数据库内容的录入,就需要考虑修改和删除(当然你直接打开数据库像操作Excel一样也是一种方法,但是不推荐这么做),在做页面之前需要注意,我们用了一个tabcontrol来更好的管理整个程序布局,在代码上也要划区域,不要搞得很乱,所有跟试题录入相关的方法都放在一起,并用一个region括起来(跟全局的也要分开)

整个试题查看的界面设计如下,为了方便快速查看试题,还需要做上一题/下一题的按钮(或者像很多网页一样显示1-10条,11-20条这种十个记录一次显示,我们都会在下面讲到,在试题查看的时候我们把试题的ID也显示出来了,而在试题录入的时候是没有的,因为只有执行完毕才会生成一个唯一的ID,这里试题查看/修改/删除都是根据这个唯一的ID来的,而不是编号)

在切换到试题查看页面的时候,我们需要遍历数据库得到所有的记录,然后放到comboBox给用户随时选择切换试题(这里写了一个DataBaseQuestionGetALL的方法,就是对数据库的所有记录根据某个字段升序或者降序提取出来,参考前面一章直接把ACCESS读取并放到DataGridView显示的功能,这里我们也用到了类似的功能)

这里我们做了一个List可变数组,把所有记录放在List中,但是其实这样做在真实的项目中还是会有问题,比如一个淘宝商品有太多属性,商品描述包含的图片,文字信息有几千个字符,你一条记录就很大,几十万条几百万条记录要统统存到一个List里面你程序就卡死了(而实际上我们目的只是要方便用户快速选择试题,所以只列举跟当前试题编号接近的10个题目就行了)

所以就有了"上一题","下一题"的功能需求。比如我要选择试题编号比当前NO大的三条,并且从小到大排序,或者要选择比当前NO小的一条,就可以使用较为复杂的Select语句,你需要 Top X * 并且添加order by XXX, asc或者desc分别表示升序和降序(第一依据是Question_NO的升序,第二依据是ID的升序,因为第一依据不是主键,可能会有重复的Question_NO,或者按试题分数,限制时间排序都不一定是唯一的,如果不唯一这个select语句就可能不按照你的提示选出来指定的记录数,所以最后要再跟一个唯一的主键ID的排序)

修改此题也比较好理解了,注意跟前面一样,传入的是一个结构体类型,修改成功或者失败都有返回值

删除也比较好理解,只不过删除了这一题,为了提高用户体验,还需要直接刷新到下一题(如果真的要做优化还是有很多判断没有做,比如当前就是最后一题,那么就跳到上一题或者第一题,删除之前弹出个确认框之类的)

更多教学视频和资料下载,欢迎关注以下信息:
我的优酷空间:
http://i.youku.com/acetaohai123

我的在线论坛:
http://csrobot.gz01.bdysite.com/

问题交流:
QQ:910358960
C#基础视频教程6.2 如何简单读写数据库的更多相关文章
- C#基础视频教程6.1 如何简单读写数据库
要理解MySQL,SQLServer,ACCESS都是数据库的品牌,不同品牌的数据库在不同的领域,适用场合有所不同.ACCESS应该是最简单,至少是Windows上最容易上手的数据库,MySQL可能跟 ...
- C#基础视频教程6.3 如何简单读写数据库
在继续往下做之前,我们需要把之前的代码尽可能的精简(会对后面很有好处,而且读者也应该仔细比对这一部分的代码和上一部分哪里真正得到了优化,从而提高编程水平). 首先数据库的操作类有哪些是可以做的更加普遍 ...
- C#基础视频教程5.3 如何编写简单的超级热键
跟前面一章讲解计算器一样,到最后一小节,我们总是要把代码规整好,让整个程序显得非常简洁,先做个文件夹把我们自定义的类库都放进去 然后我们开始整理Form1里面的代码,为了实现超级热键的功能,我们应 ...
- JavaScript基础视频教程总结(131-140章)
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...
- JavaScript基础视频教程总结(081-090章)
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...
- JavaScript基础视频教程总结(001-010章)
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...
- JavaScript基础视频教程总结(011-020章)
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...
- Java入门到精通——基础篇之多线程实现简单的PV操作的进程同步
Java入门到精通——基础篇之多线程实现简单的PV操作的进程同步 一.概述 PV操作是对信号量进行的操作. 进程同步是指在并发进程之间存在一种制约关系,一个进程的执行依赖另一个进程的消 ...
- python3基础视频教程
随着目前Python行业的薪资水平越来越高,很多人想加入该行业拿高薪.有没有想通过视频教程入门的同学们?这份Python教程全集等你来学习啦! python3基础视频教程:http://pan.bai ...
随机推荐
- Linux check whether hyperthreading is enabled or not
There parameters need to be obained: no. of physical CPU; no. of cores on each CPU; no. of all threa ...
- pair 对组
pair 对组 c++ 基础 2016-05-10 19:42 154人阅读 评论(0) 收藏 举报 分类: 头文件的函数精粹(12) 版权声明:本文为博主原创文章,未经博主允许不得转载. 与关联 ...
- 【BZOJ 2024】 2024: [SHOI2009] 舞会 (容斥原理+高精度)
2024: [SHOI2009] 舞会 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 368 Solved: 102 Description OIto ...
- listView 一个 item更新
韩梦飞沙 韩亚飞 313134555@qq.com yue31313 han_meng_fei_sha 1,更新对应的 view 的内容 2,通过viewHolder去 设置 值 3,调用一次 ...
- [APIO2014]序列分割 --- 斜率优化DP
[APIO2014]序列分割 题目大意: 你正在玩一个关于长度为\(n\)的非负整数序列的游戏.这个游戏中你需要把序列分成\(k+1\)个非空的块.为了得到\(k+1\)块,你需要重复下面的操作\(k ...
- 【HDU】6410:序列期望
序列期望 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submis ...
- noip200204过河卒
如图,A 点有一个过河卒,需要走到目标 B 点.卒行走规则:可以向下.或者向右.同时在棋盘上的任一点有一个对方的马(如上图的C点),该马所在的点和所有跳跃一步可达的点称为对方马的控制点.例如上图 C ...
- python开发_random
和java中的random()函数一样,在python中也有类似的模块random,即随机数 下面是我做的demo 运行效果: ==================================== ...
- HashMap结构及使用
HashMap的数据结构 HashMap主要是用数组来存储数据的,我们都知道它会对key进行哈希运算,哈系运算会有重复的哈希值,对于哈希值的冲突,HashMap采用链表来解决的.在HashMap里有这 ...
- C++入门级 一
如果您想学习电脑编程,却又不知从何入手,那么您不妨看看下面的几种学习方案,可能会给您一些启示吧! 方案一 Basic语言 & Visual Basic 优点 (1)Basic 简单易学,很容易 ...