---------------------- Windows Phone 7手机开发、.Net培训、期待与您交流! ------------------
小小的感想:越是长大,发现时间走得也越快,这两年过得比以往任何时候都快,最大的收获就是找到了职业方向,那就是做一名优秀的.net程序员,这个目标在去年12月份就已经确定了,虽然一直在学视频,真正投入的却不多,每天不是早上五点多起床,就是凌晨四五点睡觉,根本没多少时间,而且上完班确实累,所以完全不在状态,就这样过了几个月,虽然把视频全部看完而且把视频上的代码跟着敲了一遍,事实上并没有掌握多少。上班的时候总是想着,一定要把握好下班后的每一时每一刻,下班后听听音乐看看空间什么的一过又是几个小时,接下来累了又想休息,想等以后进了黑马就可以全心全意投入了。今天很快就要过去,明天很快就要到来,等待你的不是别的,是流水线。长达十小时的流水线,因为对自己的屡屡食言,我终于不再相信自己,不相信一个把握不好现在的人,能把握好未来。现在要做的,就是把握现在,就算在工作,也要把没有弄明白的代码写在纸上放在身边,有空就看。七月底两年的合同到期,在合同到期之前拿到黑马的录取通知书,是现阶段的目标。
我不知道自己是否有天份做程序员,这一次我会尽自己最大的努力去把它学好,学精。
Ado.Net实现程序和数据库的交互,为各种不同的数据库提供统一接口,实现应用程序和数据库的联接。
程序要通过联接字符串指定要联接哪台服务器上的哪个实列的哪个数库库,用什么用户名密码等,因为程序默认会去连接Bin/Debug下的mdf文件,而不是项目中的mdf文件,所以当插入修改数据库中的数据在运行程序后项目中数据库的数据并不发生变化,为了让程序去连接项目中的mdf文件,而不是连接bin/Debug下那个要在Program.cs文件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);
}
创建数据库的联接Connection conn= new SqlConnection(@” DataSource=.\SQLEXPRESS;AttachDBFilename=|DataDirectory|\Database1.mdf;IntegratedSecurity=True”)
如果多次联接而联接发生变化时需要对每个联接字符串进行修改很麻烦,有一种方法就是把连接子符串放到配置文件中,这样只要修改配置文件中的数据就可以了。在配置文件中
<configuration>
<connectionStrings>
<add name="connstring" connectionString="连接字符串"/>
</connectionStrings>
</configuration>
然后添加引用System.Configuration
string strcoon = ConfigurationManager.ConnectionStrings["connstring"].ConnectionString;
将连接字符串放到变量strcoon中,用的时候就可以用变量strooon代替了。
数据的导入
思路:目的只有一个就是把文件中的数据导入到数据库。首先要获得文件路径,获得所有要导入的文件并取出文件中的数据。用Directory. GetFiles(stringpath, string searchPattern, SearchOption searchOption)获取所有的文件,用一个foreach循环遍历所有的文件file, Path.GetFileNameWithoutExtension(file)获得文件名,File.ReadAllLines(file, Encoding.Default)提取文件中的数据,注意加上Encoding.ASCI,因为文件中的数据为ASCI码,而程序运行的是UTF-8码,否则会出现乱码。
代码如下:
public partial classForm1 : Form
{
publicForm1()
{
InitializeComponent();
}
private voidbtnimport_Click(object sender, EventArgs e)
{
FolderBrowserDialogfbdlg = new FolderBrowserDialog();
if(fbdlg.ShowDialog() != DialogResult.OK)
{
return;
}
stringpath = fbdlg.SelectedPath;
stringstrconn = ConfigurationManager.ConnectionStrings["strconn"].ConnectionString;
using (SqlConnectionconn = new SqlConnection(strconn))
{
conn.Open();
using(SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "delete from TablePhoneNumber";
cmd.ExecuteNonQuery();
}
}
string[]files = Directory.GetFiles(path, "*.txt", SearchOption.AllDirectories);
using (SqlConnectionconn = new SqlConnection(strconn))
{
conn.Open();
using(SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "insert intoTablePhoneNumber(startNumber,endNumber,name)values(@startNumber,@end,@address)";
foreach (string file in files)
{
string nameth.GetFileNameWithoutExtension(file);
string[] lines = File.ReadAllLines(file, Encoding.Default);
foreach (string line in lines)
{
string[] strs =line.Split('-');
string StartNumber= strs[0];
string EndNumber =strs[1];
string Address =strs[2];
cmd.Parameters.Clear(); cmd.Parameters.Add(newSqlParameter("startNumber", StartNumber));
cmd.Parameters.Add(newSqlParameter("end",EndNumber));
cmd.Parameters.Add(newSqlParameter("address", name+Adress));
cmd.ExecuteNonQuery();
}
}
}
}
MessageBox.Show("导入成功");
}
private voidbtnsearch_Click(object sender, EventArgs e)
{
stringstrconn = ConfigurationManager.ConnectionStrings["strconn"].ConnectionString;
using (SqlConnectionconn = new SqlConnection(strconn))
{
conn.Open();
using(SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "select * from TablePhoneNumber wherestartNumber<=@inputnumber and endNumber >=@inputnumber";
cmd.Parameters.Add(new SqlParameter("inputnumber",textBox1.Text));
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader.Read())
{
string name =reader.GetString(reader.GetOrdinal("name"));
MessageBox.Show("号码归属地:" + name);
}
else
{
MessageBox.Show("归属地未知");
}
}
}
}
}
}
导入到数据库。
创建一个名为Database1.mdf的数据库,在数据库添加一个名为T_M的表,在表中有主键Id(自增类型),Name,Age。
输出当前插入数据的Id的值:在Values前添加OUTPUT inserted.Id
INSERTINTO T_M(Name, Age) OUTPUT inserted.Id VALUES('wolf', 100)
首先创建数据库联接。
SqlConnection conn = new SquConnection(@"DataSource=.\SQLEXPRESS;AttachDBFilename=|DataDirectory|\Database1.mdf;IntegratedSecurity=True");实现了IDisponse接口故可用Using(){}进行资源释放。
打开数据库联接:conn.open();
创建查询命令:SqlCommand cmd = conn.CreateCommand();
插入一条数据Cmd.CommandText= insert intoT_M(Name,Age) values (‘huangzhong’,24);
Cmd.ExecuteNonQuery();执行的不是查询语句。
得到自增字段Id的值:INSERT INTO T_M(Name, Age) OUTPUT inserted.Id VALUES ('wolf', 100)
Cmd.ExecuteScalar()返回一个一行一列的Object类型的数据。
将其转换为Int类型输出:int I = convert.toint32(Cmd.ExecuteScalar());
Console.writeline(“新插入数据的主键值Id为”,i);
ExecuteScalar只返回单个列序列号,要执行有多行结果返回用ExecuteReader,reader的getstring,getint32等方法只接受Int参数,也就是序列号第几列的值,用GetOrdinal方法根据列名动态获得序号.就是根据列名(字段名)获取序列号。如:
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{一个布尔类型的数据,只要有数据就会一条条往下读,直到没有数据返回False; Console.WriteLine(reader.GetString(1));读取列号为1的数据
Console.writeline(reader.getstring(reader.getordinal(“Name”));根据字段名获取列号,再读取显示出来。
}
用Using释放资源,内部会自动调用Close及Disponse,Close只是暂时关闭,还可以打开使用,Disponse则是销毁无法再用了。
以下是一个登录程序:
Console.WriteLine("please input your name");
stringusername = Console.ReadLine();
Console.WriteLine("pleaseinput key");
stringpassword = Console.ReadLine();
using (SqlConnectionconn = new SqlConnection(@"DataSource=.\SQLEXPRESS;AttachDBFilename=|DataDirectory|\Database1.mdf;IntegratedSecurity=True"))
{ conn.Open();
using(SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "select * from mytable 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("successopen data connection ");
Console.ReadKey();
还可以用另外一种方法,但是有漏洞,如果输入密码为1 ’or’ 1 ‘=’1同样可以登录。
Console.WriteLine("please input your name");
string username = Console.ReadLine();
Console.WriteLine("pleaseinput key");
string password = Console.ReadLine();
using (SqlConnectionconn = new SqlConnection(@"DataSource=.\SQLEXPRESS;AttachDBFilename=|DataDirectory|\Database1.mdf;IntegratedSecurity=True"))
{ conn.Open();
using(SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "select count(*) from mytable where UserName=usernameand Password =password”
int I = convert.toint32(cmd.executeScalar());
if(i)>0{console.writeline(“登录成功“)
else{console.writeline(“用户名或密码错误“);
}
}
Console.WriteLine("successopen data connection ");
Console.ReadKey();
解决方法:用占位符@name和@pass代替分别username和password赋值给UserName及Password,然后用参数传递。
将cmd.CommandText = "select count(*) frommytable where UserName=username and Password =password”改为:
Cmd.commandText=”select count(*) from mytable whereUserName = @name and Password=@pass”;
cmd.Parameters.Add(new SqlParameter("name",username));
cmd.Parameters.Add(new SqlParameter("pass",password));
cmd.Parameters.Add(new SqlParameter("pass",(object)1);如果是常量则需要转换为Object类型。
为了避免写重复代码,可以把ExecuteNoQUery,ExecuteScalar等进行封装,在程序中只要调用主可以了,创建一个SQLhelp类,在类中进行封装:
class SQLhelp
{
public staticint ExecuteNonQuery(string sql, params SqlParameter[] parameters)
{
stringconnstring = ConfigurationManager.ConnectionStrings["connstring"].ConnectionString;
using (SqlConnectionconn = new SqlConnection(connstring))
{
conn.Open();
using(SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = sql;
foreach (SqlParameter parameter in parameters)
{
cmd.Parameters.Add(parameter);
}
return cmd.ExecuteNonQuery();
}
}
}
public staticobject ExecuteScalar(string sql, params SqlParameter[] parameters)
{
stringconnstring = ConfigurationManager.ConnectionStrings["connstring"].ConnectionString;
using (SqlConnectionconn = new SqlConnection(connstring))
{
conn.Open();
using(SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = sql;
foreach (SqlParameter parameter in parameters)
{
cmd.Parameters.Add(parameter);
}
return cmd.ExecuteScalar();
}
}
}
public staticSqlDataReader ExecuteReader(string sql, params SqlParameter[] parameters)
{
stringconnstring = ConfigurationManager.ConnectionStrings["connstring"].ConnectionString;
using (SqlConnectionconn = new SqlConnection(connstring))
{
conn.Open();
using(SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = sql;
foreach (SqlParameter parameter in parameters)
{
cmd.Parameters.Add(parameter);
}
return cmd.ExecuteReader();
}
}
}
public staticDataTable ExecuteDataTable(string sql, params SqlParameter[] parameters)
{
stringconnstring = ConfigurationManager.ConnectionStrings["connstring"].ConnectionString;
using (SqlConnectionconn = new SqlConnection(connstring))
{
conn.Open();
using(SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = sql;
foreach (SqlParameter parameter in parameters)
{
cmd.Parameters.Add(parameter);
}
DataSet dataset = new DataSet();
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
adapter.Fill(dataset);
return dataset.Tables[0];
}
}
}
}
更新DataSet的数据:可以更新行row[“Name”]=”Ariel”,删除行dataTable.Rows.Remove(),新增行dataTable.NewRow()。这些操作都只是修改内存中的DataSet,并没有修改数据库中的数据。
要修改数据库中的数据要调用SqlDataAdapter的Update方法对DataSet的修改提交到数据库。Updata方法有很多重载,可以提交整个DataSet,DataTable,或若干个DataRow,但是需要为SqlDataAdapter提供UpdateCommand,InserCommand,UpdateCommand才知道如何将DataSet的修改提交到数据库,可以用SqlCommandBuilder自动生成这几个Command,用法:SqlcommandBuilder builder =new SqlCommandBuilder(adapter)
C#中值类型是不能为空的,只要在类型后加?就构成了可空的数据类型,如:Int类型数据是不能为NULL的,int?表示可空的int。
弱类型DataSet的缺点:只能通过列名来引用,写错了编译不会发现错误,必须记住列名,从DataSet中取来的的数据类型都是Object类型,,使用时要进行类型转换麻烦且容易出错。将DataSet传递给其它使用者,使用者很难识别哪些列可以使用,运行时才能知道所有列名,数据绑定麻烦。
因此,我们可以自己动手写强类弄DataSet,即类型化DataSet。封装属性和方法等直接调用。
强类型DataSet的创建方法,建一个数据集,将表拖到数据集中就创建了一个强类型DataSet。
用法:首先New一个TabeAdapter,表名+TableAdapter adapter=new表名+TableAdapter();
表名+DataTable datatable = adapter.getData();
----------------------- Windows Phone 7手机开发、.Net培训、期待与您交流! ---------------------- 详细请查看:http://net.itheima.com/