一.登陆及错误处理
切记:在编写代码的时候要多考虑可能出错的地方,尽量避免无法预知的错误。
private void Button_Click(object sender, RoutedEventArgs e)
{
if (this.txt_UserName.Text.Length <= 0)
{
MessageBox.Show("用户名不能为空!");
}
else if (this.txt_PassWord.Password.Length <= 0)
{
MessageBox.Show("密码不能为空!");
}
else
{
string username = this.txt_UserName.Text.Trim();
string userpwd = this.txt_PassWord.Password.Trim();
DataTable dt=SqlHelper.ExecuteDataTable("select * from T_User where UserName=@userName",new SqlParameter("@userName",username));
if (dt.Rows.Count <= 0)
{
MessageBox.Show("该用户不存在!");
}
//不可能存在的问题,断言:
else if (dt.Rows.Count > 1)
{
throw new Exception("用户名重复!");
//MessageBox.Show("用户名重复!");
}
else
{
string pwd =(string)dt.Rows[0]["UserPwd"];
long id = (long)dt.Rows[0]["Id"];
int errortimes = (int)dt.Rows[0]["ErrorTimes"];
if (errortimes >= 3)
{
MessageBox.Show("密码输入超过三次,用户已锁定!");
}
else if (pwd == userpwd)
{
MessageBox.Show("登陆成功!");
}
else
{
SqlHelper.ExecuteNonQuery("update T_User set ErrorTimes=ErrorTimes+1 where Id=@id ",new SqlParameter("@id",id));
MessageBox.Show("登陆失败!");
}
}
}
}
二.导入与导出:
在处理较少信息量的数据导入导出,最好使用File.ReadLines()方法,数据信息量较大的时候要使用FileStream,可以与DataSet与SqlDataReader比较着看待
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "文本文件|*.txt";
if (ofd.ShowDialog() == false)
{
throw new Exception("浏览框不能正常弹出");
}
else
{
string filename = ofd.FileName;
//File.ReadLines(path,编码格式);这里的编码格式使用Encoding.Default系统编码格式
//如果不选择系统编码格式,会出现录入结果乱码;
//导入到数据库,会出现乱码的地方有两个:
//1.可能在读取的时候出现乱码(保存的编码格式与读取的编码格式不同),这是最容易出乱码的原因;
//2.导入数据库乱码,一般不会出现,几率较小
IEnumerable<string> lines = File.ReadLines(filename, Encoding.Default);
foreach (string line in lines)
{
string[] arr = line.Split('-');
string name = arr[0];
string age = arr[1];
SqlHelper.ExecuteNonQuery("insert into T_UserInfo(UserName,UserAge) values(@name,@age)",new SqlParameter("@name",name),new SqlParameter("@age",Convert.ToInt32(age) ));
}
MessageBox.Show("导入完成!");
}
三.分隔,交互,时间段
1.如果电话号码薄.txt文件每两个字符直接用制表符分隔,
分隔的话使用:string[] strs=line.Split(‘\t’);//在vs中不支持”Tab”分隔,使用‘\t’为制表符
2如果电话号码薄.txt文件中存在字符,如“北京”,VS不会自动去除双引号,要使用代码去除:city=city.Trim(‘”’);前后去除双引号
3.如果对于较大的信息量的导入,不要完全依赖于SqlHelper,要学会手写,不要打开,插入一行,关闭。。。。。,要打开,一直插入完毕,再关闭,效率更好!
4.TimeSpan ts=DateTime.Now-startTime;现在时间-开始时间,返回值是TimeSpan类型
Double zongmiaoshu=ts.TotalSeconds;时间端的总毫秒数
四.Null在数据库
Null在数据库中表示”不知道”
Select 1+0 运行结果是1
Select 1+Null 运行结果是Null
五.DBNull
在正规项目中对于Null处理是非常严谨的!!!如果用户没有输入,则数据库中以Null显示,表示“不知道”,如果数据空中Null,则在项目中转换为DBNull,再显示
1.录入过程DBNull
private void bt_OK_Click(object sender, RoutedEventArgs e)
{
//数据库中的Null表示“不知道”
//需求:姓名不输,数据库中为Null;年龄不输,数据库中为Null
//可是如下代码不能满足需求需要改进
//用户姓名不输入,年龄32
//数据库中 32
//string name = this.txt_UserName.Text.Trim();
//string age = this.txt_UserAge.Text.Trim();
//SqlHelper.ExecuteNonQuery(@"insert into T_UserInfo(UserName,UserAge) values(@username,@userage)",
//new SqlParameter("@username",name),
//new SqlParameter("@userage",age));
虽然这里数据库会把String类型转换成Int类型,但是增加了数据库运行的负担,所以还是需要代码转换(前提是确保年龄框输入值,如果不输入值,则会报错的!)
//MessageBox.Show("成功录入!");
//下面这种,VS中的null不能转换为数据库中的Null不知道,
//用户名输入admin,年龄输入框不输入值
//数据库中会插入admin 0
//string name = this.txt_UserName.Text.Trim();
//string age = this.txt_UserAge.Text.Trim();
//if (name.Length <= 0)
//{
// name = null;
//}
//if (age.Length <= 0)
//{
// age = null;
//}
//SqlHelper.ExecuteNonQuery(@"insert into T_UserInfo(UserName,UserAge) values(@username,@userage)",
//new SqlParameter("@username", name),
//new SqlParameter("@userage", Convert.ToInt32(age)));
虽然这里数据库会把String类型转换成Int类型,但是增加了数据库运行的负担,所以还是需要代码转换
//MessageBox.Show("成功录入!");
//引入DbNull来解决这个问题
string name = this.txt_UserName.Text.Trim();
string age = this.txt_UserAge.Text.Trim();
//if (name.Length <= 0)
//{
// name = DBNull.Value;//这里DBNull为一个Class类,无法实现与String的类型转换;
// //但是:.Net中的所有的类都继承Object,Object可以有String进行类型转换
//}
//if (age.Length <= 0)
//{
// age = null;
//}
object objname;
object objage;
if (name.Length <= 0)
{
objname = DBNull.Value;
}
else
{
objname = name;
}
if (age.Length <= 0)
{
objage = DBNull.Value;
}
else
{
objage = age;
}
SqlHelper.ExecuteNonQuery(@"insert into T_UserInfo(UserName,UserAge) values(@username,@userage)",
new SqlParameter("@username", objname),
new SqlParameter("@userage",objage));
//虽然这里数据库会把String类型转换成Int类型,但是增加了数据库运行的负担,所以还是需要代码转换
MessageBox.Show("成功录入!");
}
2.显示过程DBNull
private void button1_Click(object sender, RoutedEventArgs e)
{
DataTable dt = SqlHelper.ExecuteDataTable("select * from T_UserInfo where Id =16");
//数据库中Id=15的这一行中姓名为Null ,年龄为32
//按照下面这种做法是不能够对的,因为数据库中存放的Null是不知道,需要VS与数据库进行比较
//DBNull(VS) 与Null(数据库)
//string name = dt.Rows[0]["UserName"].ToString();
//int age = (int)dt.Rows[0]["UserAge"];
//this.txt_UserName.Text = name;
//this.txt_UserAge.Text = age.ToString();
string name;
if (dt.Rows[0]["UserName"] == DBNull.Value)
{
name = null;
}
else
{
name=(string)dt.Rows[0]["UserName"];
}
int? age;//int 类型和string 类型是不同的
//int 不能为空,string 可以为空,但是int ?可以为空
if (dt.Rows[0]["UserAge"] == DBNull.Value)
{
age = null;
}
else
{
age = (int)dt.Rows[0]["UserAge"];
}
this.txt_UserName.Text = name;
this.txt_UserAge.Text = age.ToString();
}