代码改变世界

WebMatrix之WebMatrix.Data

2012-04-04 23:34  Ecin  阅读(2197)  评论(0编辑  收藏  举报

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,将会抛出异常:

image

但是可以在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);
            }

 

抛出的异常为:

image

一个很常见的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:

image

 

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";
            }

带上数据库文件所在目录即可,至于为什么要这样写,待续。