最近帮老婆写一个小程序,用C#写一个简单的银行业务知识考试系统,试题存放在Access数据库中,需要随机抽取N条记录生成试卷,原本打算用sql的办法生成随机记录,但是似乎每次选出来的试题并不刷新,于是,我采用了如下办法,方法似乎笨了点,但总算搞定,希望大家可以给出更好的解决办法。
1. 得到记录总数T
2. 生成1到T的N个不重复的随机数
3. 根据得到的随机数取出相应行数的记录
代码片段如下:
1. 得到记录总数:
lnk = new LinkAccessDB(strDBFile, "", strPwd);
lnk.OpenDB();
strSql = "select count(*) as num from tb_question_sglsel";
dt = lnk.ExecQuerySql(strSql);
nTotalSglSelNum = Convert.ToInt32(dt.Rows[0]["num"].ToString());
2. 生成不重复的随机数:
private static int[] GetRandom(int nMinValue, intnMaxValue, int nCount)
{
Random rnd = new Random();
int nLength = intnMaxValue- nMinValue + 1;
byte[] keys = new byte[nLength];
rnd.NextBytes(keys);
int[] items = new int[nLength];
for (int i = 0; i < nLength; i++)
{
items[i] = i + nMinValue;
}
Array.Sort(keys, items);
int[] result = new int[nCount];
Array.Copy(items, result, nCount);
return result;
}
arrSglSel = GetRandom(1, nTotalSglSelNum, nSglSelNum);
3. 根据得到的随机数取出相应行数的记录,存放到Hashtable中
Hashtable hsSglSel = new Hashtable(); //存放单选题信息(key+试题信息)
Paper_SglSel ss = new Paper_SglSel(); //单选题试题信息
lnk = new LinkAccessDB(strDBFile, "", strPwd);
lnk.OpenDB();
for (i = 0; i < nSglSelNum; i++)
{
//Access不支持RowNum,只好拼sql
strSql = "select top 1 * from (" + "select top ";
strSql += arrSglSel[i].ToString();
strSql += " * from tb_question_sglsel order by id asc) order by id desc";
// Console.WriteLine(strSql);
dt = lnk.ExecQuerySql(strSql);
if (dt.Rows.Count <= 0)
{
bOK = false;
break;
}
ss.id = dt.Rows[0]["id"].ToString();
ss.content = dt.Rows[0]["content"].ToString();
ss.ans_A = dt.Rows[0]["ans_A"].ToString();
ss.ans_B = dt.Rows[0]["ans_B"].ToString();
ss.ans_C = dt.Rows[0]["ans_C"].ToString();
ss.ans_D = dt.Rows[0]["ans_D"].ToString();
ss.ans_E = dt.Rows[0]["ans_E"].ToString();
ss.answer = dt.Rows[0]["answer"].ToString();
ss.your_answer = "?";
hsSglSel.Add(i + 1, ss);
}
其中,Paper_SglSel为自定义的struct,结构如下:
public struct Paper_SglSel
{
public string id;
public string content;
public string ans_A;
public string ans_B;
public string ans_C;
public string ans_D;
public string ans_E;
public string answer; //标准答案
public string your_answer; //考生的答案
}
此方法虽可以搞定问题,但效率不高,也请大家共同探讨,已将全部程序上传到CSDN的下载频道,有兴趣的朋友可以下载下来试试 :《银行业务知识考试系统》,好像是这个名字。晕!