---------------------- Windows Phone 7手机开发 、.NET培训、期待与您交流!----------------------
1.ADO.NET 连接SQLServer
ADO.NET 中提供了对各种不同数据库的统一操作接口。
内嵌MDF文件:添加一个“基于服务的数据库”,生成一个MDF文件,在程序中通过连接字符串将这个MDF文件attach 到SQL Server,
连接结束后自动分离。MDF文件随着项目走,用起来方便,和在数据库服务器上创建数据没什么区别,运行的是会自动附和(attach)。
附加:SQL server 2008 中数据库/附加/选择MDF 文件
分离
用时,在控制台,WInForm项目中在Main函数最开始的位置加入以下代码:
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);
}
2.连接SQLServer
连接字符串:程序通过连接字符串制定要连哪台服务器上的、哪个势力的哪个数据库、用什么用户名和密码等。
项目内嵌mdf文件形式的连接字符串:
"Data Source=.\SQLEXPRESS;AttachDBFilename=|DataDirectory|\Database1.mdf;Integrated Security=True;User Instance=True"
".\SQLEXPRSS"表示本机上的SQLEXPRSS实例,如果数据库实例名不是SQLEXPRESS,则需要修改,"Database1.mdf"为mdf的文件名。
"Database1.mdf" 文件名
ADO.NET 中通过SqlConnection 类创建到SQLServer的连接,SqlConnection代表一个数据库连接。
ADO.NET 中的SqlConnection、SqlCommand、SqlDataReader以及FileStream连接等资源都实现了IDisposable 接口,可以使用using进行资源管理。
当using的{}中的代码执行完了,就会自动关闭和释放对象所占用的资源。程序第一次连接数据库很耗时,因此对同一个数据库的连接不要重复连接,应该设为一个全局变量。
static void Main(string[] args)
{
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);
}
using (SqlConnection conn = new SqlConnection(@"Data Source=.\SQLEXPRESS;AttachDBFilename=|DataDirectory|\Database1.mdf;Integrated Security=True;User Instance=True"))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "Insert into MyTable1(Name) values('abc')";
cmd.ExecuteNonQuery(); //执行一个非查询语句
Console.WriteLine("插入成功!");
}
}
Console.WriteLine("OK!");
Console.ReadKey();
}
3.用户登录判断
class Program
{
static void Main(string[] args)
{
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);
}
Console.WriteLine("请输入用户名:");
string username=Console.ReadLine();
Console.WriteLine("请输入密码:");
string password=Console.ReadLine();
using (SqlConnection conn = new SqlConnection(@"Data Source=.\SQLEXPRESS;AttachDBFilename=|DataDirectory|\Database2.mdf;Integrated Security=True;User Instance=True"))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "select * from T_Users where UserName='"+username+"'";
using (SqlDataReader reader=cmd.ExecuteReader ())
{
if (reader.Read())
{
string dbpassword = reader.GetString(reader.GetOrdinal("Password"));
if (password == dbpassword)
{
Console.WriteLine("登录成功!");
}
else
{
Console.WriteLine("密码错误,登录失败!");
}
}
else
{
Console.WriteLine("用户名错误!");
}
}
}
}
Console.WriteLine("OK!");
Console.ReadKey();
}
}
4.向表中插入数据
注意:
cmd.CommandText = "Insert into T_Users(Username,Password) values ('" + username +"','" +password +"')";
//cmd.CommandText = "Insert into T_Users(Username,Password) values(username,password)"; 单纯的添加字符串username和password
注意,字符串的拼接;values后面值的单引号 ''
User 是数据库中的关键字,在使用时,必须 [User]
好习惯:表名T_开头,字段F开头
6.ExecuteScalar
SqlCommand 的ExecuteScalar方法用于执行查询,并返回查询所返回的结果集中第一行的第一列,因为不能确定返回值的类型,所以返回值是object类型。
ExecuteScalar一般用于执行,查询表里有多少条数据,或者取表中的最大值。
ExecuteScalar 应用(查询自动生成的主键的值):
cmd.CommandText = "Insert into T_Users(UserName,Password) output inserted.id values('admin','888888')";
//得到自增字段的值
int id = Convert.ToInt32(cmd.ExecuteScalar());
Console.WriteLine("新插入的主键:{0}",id);
7.执行查询
执行有多行结果集的用ExecuteReader
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "select * from T_Users";
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read()) //每调用一次Read(),就往下读一行数据,当没数据时,返回false
{
Console.WriteLine(reader.GetString(1));
}
}
}
reader.GetString 只能得到某一列的值,只能传序号
reader的GetString,GetInt32 等方法只接受整数参数,也就是序号,用GetOrdinal方法根据列名动态得到序号。
例如 :Console.WriteLine(reader.GetString (reader.GetOrdinal("UserName")));
reader.GetOrdinal("UserName") //得到列的序号
reader.GetString (reader.GetOrdinal("UserName")) //根据序号,得到列名
读取多列的值:
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read()) //每调用一次Read(),就往下读一行数据,当没数据时,返回false
{
//Console.WriteLine(reader.GetString(1));
string username=reader.GetString (reader.GetOrdinal("UserName"));
int id = reader.GetInt32(reader.GetOrdinal("Id"));
string password = reader.GetString(reader.GetOrdinal("Password"));
Console.WriteLine("Id={0},Username={1},Password={2}",id,username,password );
}
}
为什么用using:
conn.Close 之后,还可以再open; conn.Dispose 之后不可以再open。
using在出了作用域以后调用Dispose,SqlConnection,FileStream等的Dispose内部都会做这样的判断:
(判断有没有close,如果没有close就先close,再Dispose。)
and 方法登录判断:
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "select count(*) from T_Users where UserName='"+username +"' and Password='"+password+ "'";
int i = Convert.ToInt32(cmd.ExecuteScalar());
if (i > 0)
{
Console.WriteLine("登录成功!");
}
else
{
Console.WriteLine("登录失败!");
}
}
当输入密码为:1' or '1'='1 也可以提示登录成功,造成SQL注入漏洞攻击
最佳实现方法:
using (SqlCommand cmd = conn.CreateCommand())
{
//占位符的形式,可以理解为拿着输入的内容与原有用户名和密码比较
cmd.CommandText = "select count(*) from T_Users where UserName=@UN and Password=@P";
cmd.Parameters.Add(new SqlParameter ("UN",username ));
cmd.Parameters.Add(new SqlParameter ("P",password ));
int i = Convert.ToInt32(cmd.ExecuteScalar());
if (i > 0)
{
Console.WriteLine("登录成功!");
}
else
{
Console.WriteLine("登录失败!");
}
}
8.登录练习1
用户界面中进行登录判断,输错三次禁止登陆,用数据库记录ErrorTimes.
namespace 登录练习1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void IncErrorTimes()
{
using (SqlConnection conn = new SqlConnection(@"Data Source=.\SQLEXPRESS;AttachDBFilename=|DataDirectory|\MyDB.mdf;Integrated Security=True;User Instance=True"))
{
conn.Open();
using (SqlCommand updateCmd = conn.CreateCommand())
{
updateCmd.CommandText = "update T_Users set ErrorTimes=ErrorTimes+1 whereUserName=@UN ";
updateCmd.Parameters.Add(new SqlParameter("UN", txtUserName.Text));
updateCmd.ExecuteNonQuery();
}
}
}
private void ResetErrorTimes()
{
using (SqlConnection conn = new SqlConnection(@"Data Source=.\SQLEXPRESS;AttachDBFilename=|DataDirectory|\MyDB.mdf;Integrated Security=True;User Instance=True"))
{
conn.Open();
using (SqlCommand updateCmd = conn.CreateCommand())
{
updateCmd.CommandText = "update T_Users set ErrorTimes=0 whereUserName=@UN ";
updateCmd.Parameters.Add(new SqlParameter("UN", txtUserName.Text));
updateCmd.ExecuteNonQuery();
}
}
}
private void txtLogin_Click(object sender, EventArgs e)
{
using (SqlConnection conn = new SqlConnection(@"Data Source=.\SQLEXPRESS;AttachDBFilename=|DataDirectory|\MyDB.mdf;Integrated Security=True;User Instance=True"))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "select * from T_Users where UserName=@UN";
cmd.Parameters.Add( new SqlParameter ("UN",txtUserName.Text));
using (SqlDataReader reader= cmd.ExecuteReader())
{
if (reader.Read())
{
int errorTimes = reader.GetInt32(reader.GetOrdinal ("ErrorTimes"));
if (errorTimes > 3)
{
MessageBox.Show("登陆错误次数过多,禁止登录!");
return;
}
string dbpassword = reader.GetString(reader.GetOrdinal ("Password"));
if (dbpassword == txtPassword.Text)
{
MessageBox.Show("登陆成功!");
ResetErrorTimes();
}
else
{
IncErrorTimes();
MessageBox.Show("登录失败!");
}
}
else
{
MessageBox.Show("用户名不存在!");
}
}
}
}
}
}
}
9.文件的导入导出
数据导入:从文本文件导入用户信息
if (ofdImport.ShowDialog() != DialogResult.OK)
{
return;
}
using (FileStream fileStream = File.OpenRead(ofdImport.FileName))
{
using (StreamReader streamReader = new StreamReader(fileStream))
{
using (SqlConnection conn = new SqlConnection(@"Data Source=.\SQLEXPRESS;AttachDBFilename=|DataDirectory|\Database1.mdf;Integrated Security=True;User Instance=True"))
//创建连接时非常耗时的,因此不要每次操作都创建连接
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "Insert into T_Persons(Name,Age) values(@Name,@Age)";
string line = null;
while ((line = streamReader.ReadLine()) != null)
{
string[] strs = line.Split('|');
string name = strs[0];
int age = Convert.ToInt32(strs[1]);
cmd.Parameters.Clear(); //参数不能重复添加,在while中一直用的就是一个SqlCommand对象
cmd.Parameters.Add(new SqlParameter("Name", name));
cmd.Parameters.Add(new SqlParameter("Age", age));
cmd.ExecuteNonQuery();
}
}
}
}
}
MessageBox.Show("导入成功!");
---------------------- Windows Phone 7手机开发 、.NET培训、期待与您交流!----------------------
详细请查看:http://edu.csdn.net/heima/