最近帮朋友做了个小项目。遇到了一些问题,记录如下:
1.如何使用Access
两年前用过一点Access,感觉它小问题很多,就没有再用。这次的程序是放在千兆宽网的虚拟主机上,这个虚拟主机不支持Sqlite,读取数据的时候是好的,只要往数据库里边写东西,就会报错,Some Disk I/O Error Occured。很神奇,换了一个虚拟主机试试,没有问题。说明不是我程序的问题。后来只能换成Access。用ADO.NET读取数据库其实都差不多,主要就是一个连接字串的问题,还有就是一些数据库差异要注意。
1.1 数据库连接串
<add name="ConnectionString" connectionString="data source=|DataDirectory|\we.mdb;Provider=Microsoft.Jet.OLEDB.4.0" /> 连接串很简单,只需要指定DataSource就可以,这里的|DataDirectory|是指的App_Data目录。Asp.net的这种方式可以使我们很方便的用相对路径来指定数据库文件的位置。这里的Provider采用Oledb驱动。
1.2 使用
在程序中使用是很简单的,只是把Connection,Command之前的前缀换掉就可以了。举一个例子:
public DataTable GetAll(string num,int min,int startRecord, int pageSize) { string sql = string.Format("select Num ,minPrice ,isUsed from PhoneNumber where Num like '{0}%' and isUsed=0", num); if (min != 0) { sql += "and minPrice=@p1"; } using (OleDbConnection conn = new OleDbConnection(SqlHelper.ConnStr)) { conn.Open(); OleDbCommand cmd = conn.CreateCommand(); cmd.CommandText = sql; if (min != 0) cmd.Parameters.AddWithValue("p1", min); OleDbDataAdapter adp = new OleDbDataAdapter(cmd); DataTable table = new DataTable(); adp.Fill(startRecord,pageSize,table); return table; } }
当然还要添加using:
using System.Data.OleDb; using System.Data;
ADO.NET的处理方式都是很类似的,事实上,ADO.NET有一套以Db为前缀的Connection,Command等类,这些具体的类都是继承自DbConnection,所以看起来都是一样的。
1.3 差异
上面提到,Access是很诡异的。以下列举一些我遇到的:
1.3.1 user 是关键字,如果有表名或者列名是user而没有加中括号,是会出错的。当然,一致地在所有的表名和列名外加中括号是一个良好的编程习惯。
1.3.2 直接插DateTime型的数据是会报错的,即使数据库里的字段类型确实是Date,插入的方式是把C#的DateTime型ToString()过后再插入。
1.3.3 没有bool型,或者bit型,叫yesno……
1.3.4一个命令里边不支持多条sql。这个限制也很讨厌,每次执行一个command的时候里面只能包含一条sql,非常不方便,即使是小巧如Sqlite的数据库也没有这个限制。
1.3.5 参数顺序的问题. 声明的参数顺序必须要和你往command里边添加参数的声明一致.否则很有可能什么错也不报,就是不影响结果(update的时候,其他时候没试过). Access真是{jp}数据库啊!!例如
string sql = "update [user] set WorkField=@p1, Company=@p3,IC=@p4,Contact=@p5,Phone=@p6,Mobile=@p7,Address=@p8,Email=@p9,Introduction=@p10 " + "where username=@p2"; cmd.CommandText = sql; cmd.Parameters.AddWithValue("p1", entity.WorkField); cmd.Parameters.AddWithValue("p3", entity.Company); cmd.Parameters.AddWithValue("p4", entity.IC); cmd.Parameters.AddWithValue("p5", entity.Contact); cmd.Parameters.AddWithValue("p6", entity.Phone); cmd.Parameters.AddWithValue("p7", entity.Mobile); cmd.Parameters.AddWithValue("p8",""); cmd.Parameters.AddWithValue("p9", string.IsNullOrEmpty(entity.Email)?" ":entity.Email); cmd.Parameters.AddWithValue("p10", string.IsNullOrEmpty(entity.Introduction)?" ":entity.Introduction); cmd.Parameters.AddWithValue("p2", entity.UserName); int i= cmd.ExecuteNonQuery();
这样是可以的,但是把
cmd.Parameters.AddWithValue("p2", entity.UserName);
提到前面去,就不行了,更新不了. 幸好在csdn上搜到有人也问这个问题,不然都不知道怎么搞。
2.z-index的问题。
包含在其他HTML元素内部的HTML元素的z-index只是相对于位于同一层次的元素的z-index,对其父元素之外的元素的z-index没有影响,也就是说如果父元素的z-index很小,比如是0,内部元素的z-index很高,1000.父元素相邻的元素的z-index是2,如果内部元素溢出去了,和相邻元素重合,那么被覆盖的还是内部元素。