本文属于上课学习笔记,各位大神不喜勿喷哟!!
今天写的这个快速/随机的向数据库插入大量数据的博文的例子是向数据库用户信息表中随机插入上万条信息:
在数据库StuDB中创建学生信息表:
create table TblStudent
(
intId int primary key identity,
chvStuName nvarchar(20) not null,--学生名称
dtmBirthday datetime not null,--出生日期
chvStuUid nvarchar(18) not null,--身份证号
chvStuAddress nvarchar(30) not null,--家庭住址
chvStuPhone nvarchar(11) not null--联系电话
)
go
创建Windows窗体应用程序的项目:
文件夹Files里的三个txt文本分别装的是学生住址与学生的姓与名(后面插入到数据库的数据均是根据这三个文本里的数据随机产生的)
向辅助类DataFactory写入方法
public class DataFactory
{
/// <summary>
/// 定义数组存放从文件夹Files匹配的学生的家庭住址与姓名
/// </summary>
string[] firstNames;
string[] lastNames;
string[] shengs;
string[] shis;
public DataFactory()
{
//从文件夹Files里取出数据
string filePath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Files", "FirstName.txt");
firstNames = System.IO.File.ReadAllText(filePath).Split(new char[] { ‘ ‘ }, StringSplitOptions.RemoveEmptyEntries);
filePath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Files", "LastName.txt");
lastNames = System.IO.File.ReadAllText(filePath).Split(new char[]{‘ ‘}, StringSplitOptions.RemoveEmptyEntries);
filePath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Files", "Address.txt");
string[] allLines = System.IO.File.ReadAllLines(filePath);
//得到住址中的省
shengs = allLines.Where(item => item.EndsWith("省")).ToArray();
//得到住址中的市
shis = allLines.Where(item => !shengs.Contains(item) && item.Length > 0).ToArray();
}
/// <summary>
/// 随机向数据库插入大量的数据的方法
/// </summary>
/// <param name="count"></param>
/// <returns></returns>
public List<TblStudent> GetStudents(int count)
{
//ling to sql连接字符串
StuDBDataContext dataContext = new StuDBDataContext();
//学生信息表集合
List<TblStudent> list = new List<TblStudent>();
//Random随机数
Random random = new Random();
//循环向数据库中插入要生成的数据
while (list.Count<count)
{
//根据要生成的数据条数循环随机生成学生信息数据
for (int i = list.Count; i < count; i++)
{
//实例化学生信息表
TblStudent student = new TblStudent();
//随机得到学生的姓名
student.chvStuName = firstNames[random.Next(0, firstNames.Length)] + lastNames[random.Next(0, lastNames.Length)];
//随机得到学生的身份证号
string idcard = "";
while (idcard.Length < 18)
{
idcard += random.Next(0, 10);
}
student.chvStuUid = idcard;
//随机得到学生的家庭住址
student.chvStuAddress = shengs[random.Next(0, shengs.Length)] + shis[random.Next(0, shis.Length)];
//随机得到学生的电话号码
string phone = "1";
while (phone.Length < 10)
{
phone += random.Next(0, 10);
}
student.chvStuPhone = phone;
//随机得到学生的出生日期
student.dtmBirthday = DateTime.Parse(random.Next(1950, 2000) + "-" + random.Next(1, 13) + "-" + random.Next(1, 28));
list.Add(student);
}
/***************判断生成的身份证号不能重复*******************/
//获取所有生成的身份证号
string[] allIdCards = list.Select(item=>item.chvStuUid).ToArray();
//去数据库比对已经存在的身份证号
var hasIdcards = dataContext.TblStudent.Where(item => allIdCards.Contains(item.chvStuUid)).Select(item => item.chvStuUid).ToArray();
list = list.Where(item => !hasIdcards.Contains(item.chvStuUid)).ToList();
}
return list;
}
}
窗体后台代码:
namespace BigDataGenerator
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public delegate void ChangeUIHandler(int count);
/// <summary>
/// 插入数据进度条(方法)
/// </summary>
/// <param name="progress"></param>
public void ChangeProgressBar(int progress)
{
this.progressBar1.Value = progress;
this.label2.Text = progress + "%";
}
//向数据库插入数据成功后button按钮和文本框的值可以使用(方法)
public void ChangeControlEnabled(int data)
{
this.button1.Enabled = true;
this.textBox1.Enabled = true;
}
//向数据库中插入数据
private void Generate(object data)
{
//更新进度条
this.Invoke(new ChangeUIHandler(ChangeProgressBar), 0);
int count = (int)data;
StuDBDataContext dataContext = new StuDBDataContext();
//如果用户插入数据库中的数据<100时,就直接向数据库中插入数据
if (count < 100)
{
//向数据库中插入数据
List<TblStudent> list = new DataFactory().GetStudents(count);
dataContext.TblStudent.InsertAllOnSubmit(list);
dataContext.SubmitChanges();
//更新进度条
this.Invoke(new ChangeUIHandler(ChangeProgressBar), 100);
}
//如果用户插入数据库中的数据>=100时,为了电脑不会卡死,就用线程执行
else
{
int countPerTime = 100;
int times = (int)Math.Ceiling(count * 1.0 / countPerTime);
for (int i = 1; i <= times; i++)
{
List<TblStudent> list = new DataFactory().GetStudents(countPerTime);
if (i == times)
{
list = new DataFactory().GetStudents(countPerTime + (count - (countPerTime * (i-1))));
}
//向数据库中插入数据
dataContext.TblStudent.InsertAllOnSubmit(list);
dataContext.SubmitChanges();
//更新进度条(线程安全,progressBar是由UI线程创建,而当前代码是被新创建的线程执行的,所以是不安全的.)
int progress = (int)((i * 1.0 / times) * 100);
this.Invoke(new ChangeUIHandler(ChangeProgressBar), progress);
}
}
//更新进度条(恢复成默认状态0%)
this.Invoke(new ChangeUIHandler(ChangeControlEnabled), 0);
}
private void button1_Click(object sender, EventArgs e)
{
int count = int.Parse(this.textBox1.Text.Trim());
Thread thread = new Thread(new ParameterizedThreadStart(Generate));
thread.Start(count);
//向数据库插入数据成功前button按钮和文本框的值不可以使用
this.button1.Enabled = false;
this.textBox1.Enabled = false;
}
}
}
运行效果: