WebMatrix数据访问系列目录:
在上篇文章中,我简单描述了在WebMatrix web开发工具如何简单的实现数据库的CRUD。其中,数据库访问组件WebMatrix.Data是微软专为WebMatrix打造的一个轻量型的动态数据访问组件。你可以通过单独引用WebMatrix.Data.dll程序集,来作为数据访问的轻量型组件。之所以说是轻量型的,因为该组件不支持存储过程,事物,说到底,它就是专为SSCE量身打造的。
下面简单来看看WebMatrix.Data是如何跨数据库平台工作的。
1.SQL Server 2005/2008的支持
以往神马跨数据库支持的大家见得最多的莫过于三层中的通过替换DAL的dll,工厂模式结合配置文件依赖注入实现数据库的切换。但是WebMatrix.Data现在完全不需要那么做,最简单的方式是通过配置文件配置节ConnectionString具体配置即可。下例是使用的一个控制台程序,在app.config下的ConnectionString如下:
<connectionStrings> <add name="mysqldb" connectionString="Server=.;Database=MyTestDb;User ID=sa;Password=******;" providerName="System.Data.SqlClient"/> </connectionStrings>
配置文件配置好后你可以像这样访问数据:
//sql server var db = Database.Open("
mysqldb
"); var list = db.Query("SELECT * FROM TestTable"); foreach (var item in list) { Console.WriteLine(item.Name); }
上述代码类似访问SSCE数据库一样,不同之处在于需要提供相应数据库的配置连接字符串,DataBase.Open方法传入一个命名的连接字符串“mysqldb”。
需要注意的是如果省略connectionStrings中的providerName,将会抛出异常:
但是可以在AppSettings中这么来写来防止异常的抛出从而正常访问数据库:
<appSettings> <add key="systemData:defaultProvider" value="System.Data.SqlClient"/> </appSettings>
如果既不在connectionStrings中提供providerName,也不在AppSettings中配置providerName,那么WebMatrix.Data会默认使用SSCE的SQL提供程序(System.Data.SqlServerCe.4.0)。至于为什么,下篇文章将会揭秘。
同样地,可以使用DataBase.OpenConnectionString(string connectionString)及其重载方法OpenConnectionString(string connectionString, string providerName)传入一个未命名的连接字符串来创建一个DataBase实例。
2.Oracle的支持
Oracle的测试我选用了ODP.NET(Oracle Data Provider for .net)。期间,发现了一个问题(使用了一个偷懒的写法),如果connectionStrings像这样配置:
<add name="myoracle" connectionString="Data Source=ORADB;User ID=testdb;Password=*****;" providerName="Oracle.DataAccess.Client" />
ORADB是在tnsnames.ora配置的,使用传统的方式没有任何问题:
var data = new DataTable(); using (OracleConnection connection = new OracleConnection(connectionstring)) { using (OracleDataAdapter adapter = new OracleDataAdapter("SELECT * FROM testdb.SYS_DICT a", connection)) { adapter.Fill(data); } }
但是使用WebMatrix.Data访问就会有问题:
var db = Database.Open("myoracle"); var list = db.Query("SELECT * FROM testdb.SYS_DICT a"); foreach (var item in list) { Console.WriteLine(item.DICT_NAME); }
抛出的异常为:
一个很常见的ora错误,说是不能解析连接标识符,显然是没有获取到tnsnames.ora文件中的连接部分,以为是文件读写权限问题,但是试了之后依然报错。后来采用这样的方式改写connectionStrings就没有问题:
<add name="myoracle" connectionString="Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=LOCALHOST)(PORT=1521)))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=ORADB)));User ID=testdb;Password=******;" providerName="Oracle.DataAccess.Client" />
connectionStrings中Data Source部分与tnsnames.ora文件中配置相同(希望遇到类似错误的可以作解答)。
当然,建议在真实项目中直接将tnsnames.ora部分(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=LOCALHOST)(PORT=1521)))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=ORADB)))写入connectionStrings中,这样就跟tnsnames.ora扯开关系,减少最少依赖。
补充1:
我在C/S程序中试了下通过WebMatrix.Data访问SSCE,没有半点问题。想到之前的一个项目也是C/S的,用的是xml作为客户端缓存,现在看来可以完全使用SSCE替代,代码编写会更加简洁。
更深入一点的就是客户端在服务器数据库断开的情况下,通过使用SSCE,可以正常使用临时缓存的客户端数据,在取得与服务器连接后通过后台数据同步,可以保持数据库服务器端数据更新,同样也减小了数据库服务器的压力。
补充2:
如果访问带有路径的数据库文件,例如SSCE:
ClientDB.sdf并不在程序根目录下,而在文件夹DataBase中,那么可以像这样使用WebMatrix.Data:
var db = Database.Open(@"DataBase\ClientDb"); var list = db.Query("SELECT * FROM tabletest"); foreach (var item in list) { richTextBox1.Text += "Name: " + item.Name + "\t" + "Description: " + item.DES+"\n"; }
带上数据库文件所在目录即可,至于为什么要这样写,待续。