1.第一个WinForm程序
(1) WinForm: Windows Form, .NET中用来开发Windows窗口应用程序的技术。
(2) 控件:窗口上很多元素都是相似的,因此将这些元素抽象成一些类,这些类就叫做控件。按钮(Button),文本框(TextBox),标签(Label),单选按钮(RadioButton),复选框(CheckBox)。
(3) 复习TryParse
int.TryParse:将数字的字符串表示形式转换为它的等效32位有符号整数,一个指示操作是否成功的返回值。
语法结构:public static bool Tryparse(string s,out int result);
注:TryParse方法类似与parse方法,不同之处在于TryParse方法在转换失败事不引发异常。
例如:加法计算器:
string str1=TextBox1.Text; string str2=TextBox2.text;
int i1,i2;
if(!int.TryParse(str1,out i1))
{
MessageBox.Show(“第一个数不是合法的整数!”);
Return;
}
If(!int.TryParse(str2,out i2))
{
MessageBox.Show(“第二个数不是合法的整数!”);
Return;
}
int i3=i1+i2; TextBox3.Text=Convert.ToString(i3);
(4) 文本框的几种模式:Multiline(多行),PassWordChar(密码)
(5) 控件名要有含义,控件名前缀的“潜规则”,按钮Button:btn;文本框TextBox:txt;
复选框CheckBox:cb。控件的名字要有意义!
(6) 局部变量每次运行完毕变量的值都会被销毁,下次在运行,会重新初始化,而类字段只要是一个对象,那么只要对象不销毁,就会一直保持对象的字段值。
例如:文本框实现查询出某人的成绩是里面最高的?
ADO.NET基础
- ADO.NET基础
(1) 程序要和数据库进行交互要通过ADO.NET进行,通过ADO.NET就能在程序中执行SQL语句,ADO.NET提供了对各种不同年数据库的统一操作接口。
(2) 在Winform中用到的一段代码(杨中科老师誉为神奇的代码)。嘿嘿
string dataDir=AppDomain.CurrentDomain.BaseDirectory;
if(dataDir.Endswith(@”\bin\Debug”)||dataDir.EndsWith(@”\bin\Release”))
{
dataDir=System.IO.Directory.GetParent(dataDir).Parent.Parent.FullName;
AppDomain.CurrentDomain.SetData(“DataDirectory”,dataDir);
}
原理分析:连接字符串中的DataDirectory的值就是通过AppDomain.CurrentDomain.SetData赋值过去的,如果当前程序的目录以”\bin\Debug\”或者”\bin\Release\”,则认为它是运行在Visual Studio环境中的,就取项目的目录然后赋值给DataDirectory的这个Key。
- 连接SQL Server
(1) 连接字符串:程序通过连接字符串指定要连接到那台服务器上的,那个实例的那个数据库,用什么用户名和密码。
(2) 项目内嵌mdf文件形式的链接字符串为:
“DataSource=.\SqlExpress;AttachDBFilename=|DataDirectory|\Database.mdf|; Integrated.Security=True;User InStance=True”。
注解:.\SqlExpress表示”本机上的SQLExpress实例”如果数据库实例名不是SQLExpress,则需要修改。
(3) ADO.NET中通过SqlConnection类创建到SQL Server的连接,SqlConnection代表一个数据库连接,ADO.NET中的连接等资源都实现了IDisposable接口,可以使用using进行资源管理。
(4) 释放资源的两种方法:
(1) using( ) (2) try
{ { }
catch
} {
conn.Close();
conn.Dispose();
}
- 执行简单的Insert语句
(1) SqlCommand表示向服务器提交一个命令(SQL语句等)。
CommandText属性为要执行的SQL语句,ExecuteNonQuery方法执行一个非查询语句(Update,Insert,Delete)等。
using(SqlCommand cmd=conn.CreateCommand())
{
cmd.CommandText=”Insert into myTable1(name) values(‘abc’)”;
cmd.ExecuteNonQuery();
}
(2) ExecuteNonQuery返回值是执行受影响的行数。
- 执行查询
(1) 执行有多行结果集的用ExecuteReader。
SqlDataReader reader=cmd.ExecuteReader();
While(reader.Read())
{
Console.WriteLine(reader.GetString());
}
(2) reader的GetString,GetInt32等方法只能接受整数参数,也就是序号,用GetOrdinal()方法根据列名动态得到序号。
(3) close和Dispose的区别:
1) close关闭以后还能打开。
2) Dispose:直接销毁,不能再次使用。
3) using在出了作用域以后调用Dispose,SqlConnection,FileStream等的Dispose内部都会做这样的判断,判断有没有close,如果没有close就先close在释放资源Dispose。
- ExecuteScalar
(1) SqlCommand的ExecuteScalar方法用于执行查询,并返回查询所返回的结果集中的第一行第一列,因为不能确定返回值的类型,所以返回值是object类型。
cmd.CommandText=”Select count(*) from T_Users”;
int i=Convert.ToInt32(cmd.ExecuteScalar());
(2) 得到自动增长字段的值,在values关键字前面加上output inserted.ID,其中id为主键字段名,执行结果就是输入的的主键值,用ExecuteScalar执行最方便。
cmd.CommandText=”Insert into T_Users(username,password) output inserted.ID values(‘admin’,’888888’)”;
int i=Convert.ToInt32(cmd.ExecuteScalar());
- SQL注入漏洞攻击
(1) 登录判断:select * from T_Users where username=…. and Password=…..;将参数拼接到SQL语句中。
(2) 构造恶意的password=’or’1’=’1
(3) 防范注入漏洞攻击的方法:不使用SQL语句拼接,通过参数赋值。
- 查询参数
(1) SQl语句使用@UserName表示”此处用参数代替”,向SqlCommand的Parameters中添加参数。
cmd.CommandText=”Select * from T_User where username=@username and Password=@pwd”;
cmd.Parameters.Add(new SqlParameters(“username”,”admin”));
cmd.Parameters.Add(new SqlParameters(”password”,”888888”));
(2) 参数在SQL Server内部不是简单的字符串替换,SQL Server直接用添加的值进行数据比较,因此不会有注入漏洞攻击。