【IT168技术文档】 NBear的持久化组件提供类似Linq的强类型查询语法,支持主外键关联、继承关联、多对多关联、级联更新、联结、分组、分页查询等,对应90%以上的常用SQL查询语法。并提供对内存数组的强类型查询过滤、查询缓存、对自定义SQL和存储过程的强类型查询封装等功能。
初始化Gateway
方法一,使用默认数据库。
什么是默认数据库呢?默认数据库就是定义于配置文件中的ConnectionString块的最后一个ConnectionString对应的数据库。以上一页的示例代码为例,默认数据库就是Northwind这个ConnectionString。特别的,当您的配置文件只定义了一个ConnectionString的时候,这个ConnectionString对应的数据库自然就是默认数据库。
NBear在初始化时,会自动初始化一个默认数据库的Gateway实例,可以直接通过Gateway.Default属性访问。因此,此时,您可以直接使用这个Gateway实例也无需额外的初始化工作了。
例如,您可以直接使用下面的代码返回Northwind数据库中的所有Categories:
Categories[] objs=Gateway.Default.SelectAll();
另外,您还可以调用Gateway.SetDefaultDatabase()方法来改变默认的Gateway。SetDefaultDatabase()包含多个重载版本,因为每个版本实际上对应了Gateway的构造函数的重载版本,这里就不重复列举使用方法了。简单的说,它可以像Gateway的构造函数一样(如下面的方法二和方法三)初始化Gateway并设置为默认Gateway。
方法二,使用ConnectionStringName初始化Gateway。
第二种方法是最典型也是比较推荐的初始化Gateway的方法,很多时候,我们需要连接不止一个数据库,您可以使用配置文件中的ConnectionString的name属性对应的名称来初始化Gateway。
例如,下面的代码分别为上一页的实例配置文件中的TestAccessDb和Northwind数据库初始化Gateway:
publicstaticGateway Northwind=newGateway("Northwind");publicstaticGateway TestAccessDb=newGateway("TestAccessDb");
这样初始化Gateway之后,我们就能方便的使用了,例如,同样查询Northwind数据库中的所有Categories:
Categories[] objs=Northwind.SelectAll();
方法三,使用硬编码方式初始化Gateway。
如果您不将ConnectionString定义于应用程序的配置文件中,那么,就需要直接提供ConnectionString来初始化了。下面是几个典型的初始化示例:
Gateway TestDbAccess=newGateway(DatabaseType.MsAccess,@"C:\Teddy\NBear\skeleton\Simple\website\App_Data\TestAccessDb.mdb");
Gateway Northwind=newGateway(DatabaseType.SqlServer,@"Server=(local);Database=Northwind;Uid=sa;Pwd=sa");
Gateway Northwind2=newGateway(DatabaseType.SqlServer9,@"Server=(local)\SQLEXPRESS;Database=Northwind;Uid=sa;Pwd=sa");
Gateway.Default=newGateway(DatabaseType.MySql,"Dsn=mysqltest;database=test;option=3;server=localhost;uid=root;password=sa");
Gateway.Default=newGateway(DatabaseType.Oracle,"Data Source=localhost;User ID=system;Password=sa;Unicode=True");
注意以上的代码使用了Gateway构造函数的另一个重载版本,接受一个DatabaseType参数和一个ConnectionString。这五行示例分别实例化了对应于MS
Access、MS SQL Server 2000、MS SQL Server 2005、MySql和Oracle的数据库的Gateway。
我们同样可以调用接受同样的参数列表的Gateway.SetDefaultDatabase()方法来设置当前的可以直接通过Gateway.Default属性访问的默认数据库。
使用Gateway访问数据库
一旦我们拥有了一个Gateway实例之后,我们就可以方便的使用它来进行数据库相关的操作了。
首先,Gateway.Default属性,我们前面提到过了,这个属性代表当前的默认数据库。
接着,Gateway有四个构造函数重载和三个SetDefaultDatabase()方法重载,这些在上一页如何初始化Gateway中我们已经了解其用法了,这里就不重复介绍了。
再下面就是我们的主角了:
1. Gateway.Db属性。该属性返回关联到当前Gateway的Database类的实例。Database类是一个类似于MS DAAB的Database类,当Gateway不能满足某些查询要求时,可以直接调用该类进行查询(一般不需要直接使用Database进行查询,因为Gateway已经封装了比较完备的各种查询接口了)。
2. BeginTransaction()和CloseTransaction()方法,这两个方法用于开始和关闭一个兼容于.Net 1.1语法的事务对象。我们可以注意到,下面的写操作都有一个包含tran参数的重载版本,可以象下面这样使用这两个方法来处理事务:
DbTransaction tran=Gateway.Default.BeginTransaction();try{
Gateway.Default.Insert(newEmp, tran);
Gateway.Default.Insert(newCust, tran);
tran.Commit();
}finally{
Gateway.Default.CloseTransaction(tran);
}
当然,我们知道,在.Net 2.0中,新增了System.Transactions命名空间,提供了新的TransactionScop类支持更简洁的事务处理语法,我们的Gateway当然也能以新的语法来使用,例如,等价于上面的。Net 1.1事务语法的新的事务处理语法如下:
try{using(TransactionScope scope=newTransactionScope(TransactionScopeOption.Required))
{
Gateway.Default.Insert(newEmp); Gateway.Default.Insert(newCust);
scope.Complete();
}
}catch{throw;
}
3. BuildDbColumnName()和BuildDbParamName()方法,这两个方法用于您希望手动构造SQL语句时,我们知道,不同的数据库的SQL语法会不一样,特别的,如对于列名或表名,SQL Server可以用一组[]将名称括起来以区别系统关键字及支持带空格的标名或字段名,而其他数据库可能就不支持这样的语法;再如,SQL Server数据库的参数以@ParamName这样的形式出现,而其他数据库则可能有其自己的格式。因此,这两个方法主要用于当需要手工构造SQL语句时,为您封装这类差异。
例如,如果我手工构造一个查询Categories的SQL语句如下,那么,该语句就能做到对不同的数据库透明:
stringsql=string.Format("select * from {0} where {1} = {2}", Gateway.Default.BuildDbColumnName("Categories"), Gateway.Default.BuildDbColumnName("ID"), Gateway.Default.BuildDbParamName("ID"));
4. 剩下就是各种查询方法了,所有带范型参数列表的方法一般都直接传递和返回强类型的Entity,而那些ExecuteXXX方法则允许查询手工构造的SQL或存储过程,这些ExecuteXXX方法一般会返回DataSet或IDataReader,如果有需要,可以使用EntityFactory填充数据到Entity。
主要参数说明
对于这些查询方法的参数,需要说明一下的是where和orderBy。where代表查询中的条件,也就是SQL语句中where关键字之后,orderby之前的部分。而orderBy则是SQL语句中order by关键字之后的部分。
典型的示例代码如下:
Categories obj=Gateway.Default.Select("CategoryID > @CategoryID","CategoryID desc, CategoryName",newobject[] {10});
以上的代码中,第一个参数是where参数,第二个参数是orderBy,第三个参数是传递给where中的SQL参数@CategoryID的值。如果希望SQL语法对特定数据库语法透明,可以参考上面的BuildParamName()和BuildClolumnName()方法的使用。
级联操作函数[New]
另一组需要注意的函数是Gateway.CascadeXXX形式的函数,包括CascadeInsert/CascadeUpdate和CascadeDelete函数。这些函数用于自动操作有继承关系的实体。这组函数和普通的Insert/Update/Delete的区别,他在内部使用ActiveEntity类自动实现继承体系相关实体的级联操作。
因此,当操作的实体和其它实体由继承或被继承关系,则必须使用Gateway.CascadeXXX形式的函数来更新实体。