.Net培训个人总结笔记11

学习交流,欢迎转载。转载请注明文章来源:http://www.cnblogs.com/lgjspace/archive/2011/10/12/2213782.html

注意:
并不是所有情况下的字符串拼接方式为SQL语句添加参数都会造成字符串注入漏洞攻击的,例如下面的例子:
string s = Console.ReadLine();
int age = Convert.ToInt32(s);
cmd.CommandText = "select * From T_Persons where Fage = "+ age;
此时由于变量“age”是被限定了 int 类型,这样的话该变量的值根本不可能出现像“'”、“=”之类的字符,所以是根本不能造成注入漏洞攻击的。

细节:
虽然 cmd.Parameters.Add() 和 cmd.Parameters.AddWithValue() 都能实现同样的添加查询参数的功能,但更推荐用 Add() 的方法,因为这是最标准的(.Net的对象 Parameters 中这是其接口唯一定义的方法)。

重点:
ComboBox 对象的 Items.Add() 方法添加的不仅仅只能是字符串,还可以是任意类型的项(object),例如可以把一个 Person 类的对象添加到 ComboBox 中,而这个被添加的项在 ComboBox 里对应的选项显示的是该对象调用 ToString() 后的字符串(例如这里的 Person,在选项中显示的是 Person 类的类名),要修改显示的字符串,可以通过设置 ComboBox 对象中的 DisplayMember 属性来实现。(假如 Person 的对象 p1 有一个Name属性,属性值为 Tom,要想在 ComboBox 中显示“Tom”而不是显示 p1.ToString() 后的字符串的话,只要把该 ComboBox 的 DisplayMember 属性的属性值设定为“Name”,即可实现需求。),如果不用这种方法,也可以通过用 override 来重写 p1 对象的 ToString() 方法来实现,但还是推荐前面的设置 DisplayMember 属性的方法。

重点:
在 C# 代码中建立 SQL 连接时用的连接字符串虽然可以通过用定义字符串常量的方法来实现重用,但还是不推荐,因为这种方式把字符串写死在程序文件(*.exe)中了,当程序已经被编译成应用程序(exe文件)后,如果想要修改该链接字符串则会很麻烦(需要在源代码中修改完以后再重新编译,然后再把重新编译后的程序 exe 文件发放给用户),所以推荐把字符串写到应用程序配置文件(在 WinForm 中是 App.config,在 WebForm 中是 Web.config)中,这种方式下,如果需要修改连接字符串,则只需要修改该配置文件下对应的值即可完成,而不需要对应用程序(*.exe)进行任何修改。
其中,把连接字符串写到应用程序配置文件(App.config)下的方法如下:
一:在配置文件中:
在文件的<configuration></configuration>标签中加入节点<connectionStrings></connectionString>,再在里面添加<add name = "(1)" connectionString = "(2)"/>,其中位置(1)填的是该连接字符串的名字,可以任意起,位置(2)填的是你要设定的连接字符串的内容,例如可以是:“Data Source=.\SQLEXPRESS;AttachDBFilename=|DataDirectory|\ProvinceCity.mdf;Integrated Security=True;User Instance=True”。
(注:在 <connectionStrings></connectionString> 节点中添加的连接字符串个数可以是任意的,即可以<add name = "" connectionString = ""/>任意多个的。)
二:在项目的“引用”列表中(添加对 System.Configuration 类的引用):
右键单击“引用”,选中“添加引用”,选择“.Net”标签,在下面的列表中选中“System.Configuration”,然后点击“确定”,完成添加引用的操作。
三:在需要用到该连接字符串的代码文件中:
在程序中定义一个字符串变量,并赋值如下:
string connStr = ConfigurationManager.ConnectionStrings["ConnStr"].ConnectionString;
其中中括号里面带双引号的"ConnStr"就是在配置文件下在 name 中填上的连接字符串的名字,这样,字符串变量 connStr 被赋予的值就是配置文件中 name 为 "ConnStr" 的连接字符串(connectionString的值)了。

注意:
string[] lines = File.ReadAllLines(path, Encoding.Default);
经反编译后得知,这里的 File.ReadAllLines() 的默认编码是:UTF-8。

拓展:
文件夹选择对话框:FolderBrowserDialog;

按照通配符搜索目录下的文件:
string[] Directory.GetFiles(string path, string searchPattern, SearchOption searchOption)。
(例如: Directory.GetFiles(“c:\ProgramFiles\1”, “*.txt”, SearchOption.AllDirectories) )。
Path.GetFileNameWithoutExtension(filename),得到文件的文件名(不要扩展名);
Path.Combine(string path1, string path2),将两个路径合并;
Path. GetExtension(string path),得到文件的后缀;
Path. GetFileName(string path),得到文件的文件名;
Path. GetFullPath(string path):得到文件的全路径。

技巧:
若需要为代码的运行计时,测量代码的运行速度,可以用 Stopwatch 类来实现:
Stopwatch sw = new Stopwatch();  //创建一个新的Stopwatch类的对象sw。
sw.Start();    //打开计时功能。
sw.Stop();    //暂停计时功能(注意:之前暂停过的数据在下次再Start()后都不会被清零,有累积效果)。
sw.Rtart();    //重新开始计时功能,并且把之前记录下的数据清零。
sw.Reset();    //重置计时器,并且把之前记录下的数据清零,但没有打开计时功能。

细节区别:
StreamReader 类的 ReadToEnd 或 File 的 ReadAllText、ReadAllLines、ReadAllBytes 等方法比较适合读取小体积的文件,因为这样方便利索,而且文件不大,不会很消耗内存资源,如果文件较大,则建议用 StreamReader 类的 Read()、ReadLine()、ReadBlock() 等这种一小块一小块地读取的方法,这样不但可以最大程度节省内存资源消耗,需要时还可以搭配多线程来共同实现异步传输,从而实现资源的最大化利用。

重点:
cmd.ExecuteReader() 方法返回的 SqlDataReader 类型的对象 reader(暂且命名为reader)并不是真正的存到内存上的“结果集”,它还只是充当着一个读取者(游标、指针等)的角色,每被执行一次 Read(),就命令数据库的“指针”(或“游标”)指向下一个待读取的值的位置上,如果和数据库通讯的连接一旦被断开,该 reader 就再也不能 Read() 出数据库的数据了。

区别(SqlDataReader 和 DataSet):
SqlDataReader相当于一个数据库的读取者(或者是游标、指针等),数据是通过已经打开着的连接来实时地到数据库中提取的;而 DataSet 则相当于一个离线的数据集,只需要和数据库连接一次,一次性地把所有要提取的数据全部提取出来放到 DataSet(内存的一块地方)中,此后无论连接是否断开都对 DataSet 里的数据毫无影响,但这种方式会消耗内存资源,不适合大数据量的存储,但小数据量的存储就很有优势。

课外拓展:
(下面代码中的 row 为 DataRow 类型,值为从 DataTable 类的对象中提取出的某一行的值。)
object[] cells = row.ItemArray;     //获得每一个row中的所有列的元素,返回值为一个 object 类型的数组。

注意:
对DataSet的任何修改,被修改的DataSet结果集都是保存在内存中的,没有提交到数据库中。

posted @ 2011-10-12 23:29  梁国锦  阅读(162)  评论(0编辑  收藏  举报