学习交流,欢迎转载。转载请注明文章来源:http://www.cnblogs.com/lgjspace/archive/2011/10/12/2213504.html
细节:
string id = reader.GetInt32(reader.GetOrdinal("id")).ToString();
//由于该Id字段在数据库中的类型为int,因此在C#中通过 SqlDataReader 实例提取出来时不能用 GetString() 方法,而应该用 GetInt32() 方法,否则报错。
string name = reader.GetString(reader.GetOrdinal("name"));
//同样地,由于该Name字段在数据库中的类型为nvarchar,因此在C#中通过 SqlDataReader 实例提取出来时不能用 GetInt32() 方法,而应该用 GetString() 方法,否则也会报错。
另:GetOrdinal()方法中所需传入的字段名不区分大小写,即假如数据库里写的是“Id”,而在GetOrdinal()中可以传入"id"、"iD"、"ID"等都可以,完全不影响结果。
细节:
若遇到误用了 SQL 关键字来充当表名或列名或别名等名称时,只需把该名称用中括号[]括起来即可,解决冲突问题,例如:"select [order] From T_Users"。
编码风格细节:
数据库表名推荐以“T_”开头,字段名推荐以“F”开头,这样既可大大减少命名冲突,又便于识别。
细节:
有如下面代码:
Insert Into T_Users (UserName,Password)
Output Inserted.Id
Values('admin','888888')
该代码中的第二行的功能是:返回刚刚被第一行代码Insert进去的这条数据的字段名为“Id”所对应的值,这是 VS2005 及之后才有的功能。
这种用法比较常见的用途是:查询该条被插入的数据的 Id 号或流水号等,并且通常是配合 SqlCommand 的实例的 ExecuteScalar() 方法来共同实现。
细节:
SqlDataReader的Read()方法只能一行一行顺着往下读,不能跳着读,也不能倒过来往前读,“过了这个村没有这个店”。
细节:
假设 SqlConnection 有一个实例 conn,conn.Open()、conn.Close()和conn.Dispose()是不一样的,前两个只是打开和关闭链接,但链接仍然存在,没被销毁,而Dispose()则是把链接直接销毁掉,即连链接本身都没了。
以水管来作比喻来再解释一下该现象,Open 和 Close 就相当于打开和关闭水龙头,但此时水管还在;而 Dispose 则相当于直接把水管给拆掉了。
细节:
Close:关闭以后还能打开。
Dispose:直接销毁,不能再次使用。
using 在出了作用域以后调用的是 Dispose() 方法而不是 Close() 方法。
SqlConnection、FileStream 等的 Dispose() 方法内部都会做这样的判断:判断在此 Dispose() 方法之前有没有被调用了 Close() 方法,如果没有被 Close 就先 Close 掉后再调用 Dispose() 方法。
(重要!!!!)另:假设以下情况:
SqlConnection conn = new Connection(CONNSTR);
conn.Open();
......
(1)......
......
conn.Close();
conn.Dispose();
假如在上面的这个过程中,如果在位置(1)处(即在 conn 打开之后,关闭和销毁之前的时候)程序抛出异常或者出现 return 语句,则下面的 Close() 和 Dispose() 都不会被执行,从而会导致链接一直会被占用。
注!!!这种情况可以用 using() 来代替手动的打开关闭销毁操作,这样的话就算是上面这种情况(即当 conn 还没有被 Close() 或 Dispose() 之前出现异常或return语句的情况)using也会自动帮我们Close()和Dispose()资源,因为using()相当于try catch finally的作用,就算出现异常或突然中断,也不影响finally部分的执行。
细节:
在同一个链接中,如果 SqlDataReader 没有被关闭(Close),那么是不能执行 Update之类的语句的。
细节:
给cmd.CommandText中的SQL语句引入参数的方法有两种(Parameters.Add() 和 Parameters.AddWithValue()):
假设有如下 CommandText:
cmd.CommandText = "Select * From T_Users Where UserName = @UserName";
方法1:
cmd.Parameters.Add(new SqlParameter("UserName",username));
方法2:
cmd.Parameters.AddWithValue("UserName",username);
两者效果等同。
细节:
在同一个 SqlCommand 对象中,例如有:SqlCommand cmd = conn.CreateCommand(),该语句创建了cmd 对象,此时,cmd.Parameters.Add() 和 cmd.Parameters.AddWithValue() 不能重复添加相同的参数,若必须要再次添加,则需要在再次添加之前调用 cmd.Parameters.Clear() 方法清除掉之前添加的参数,才能再次添加参数,即用 cmd.Parameters.Add() 和 cmd.Parameters.AddWithValue() 方法添加的参数必须唯一。
细节:
创建连接是非常耗时的,因此不要每次操作都创建连接,若需要连续多次重复使用,可以先暂时Close(),需要再用时再Open()。
细节:
OpenFileDialog() 类的对象的 FileName 和 FileNames 属性返回的文件名字符串是包含选中文件的绝对全路径的,而 SafeFileName 和 SafeFileNames 属性返回的文件名仅仅是文件名,不包含路径。
细节:
StreamReader 类的对象的 ReadLine() 方法要是读到没有内容的行时,返回值为 null,而不是""(空字符串)。
细节:
通过 Directory.GetFiles(path) 方法可以获取出路径“path”下的所有文件的全路径(路径包括文件名)。