最近因为公司项目的需要,使用了Eunge的DataQuicker2这个数据持久层,感觉确实像Eunge所说的代码简洁、唯美,性能很好,可惜现在没有帮助,所以记下对DQ2的使用的个人理解。有不足之处,还希望大家多多提出。本文是我第一次写BLOG,心情比较激动。J
DQ2提供了一个实体生成器,使用很简单,就不介绍软件的使用了,这里讲一下使用的技巧以及注意事项;
一:注意事项,一共有两点:
1:代码生成目录必须存在;2:命名空间用程序集的命名空间加上文件夹的形式,在介绍DQL的时候再说明原因;
二:使用的小技巧;打开代码生成器目录的CodeGenerator.exe.config文件,修改对应的
命名空间,连接字符串,输出目录的默认值,以后使用的时候便可少些输入;
好了,入正题了。在用代码生成器,创建好了实体类以后,就可以用VS建立一个类库,然后导入刚才创建好的实体代码,添加DataQuicker2的引用。就基本OK了,这里也两点需要要注意的问题
1、在实体类的Bind()方法中,请先确定
// 非DataQuicker2托管的。
Unmanaged
// 数据库自增长字段。
DbAutoIncrease
// DataQuicker2托管的INT值填充,字段类型一般应为INT类型,也可以为字符串类型,但是性能损失很大,并且不利于索引。
IntManaged
//DataQuicker2托管的GUID值填充,字段类型一般应为Varchar(32)。
GuidManaged
2、确定生成的实体属性与系统的类名,保留字的名字不同;本文结束时,我会附上修改过的代码模板,下载后覆盖原来的文件就没有这个问题了,你也可以自行修改为你习惯的模式。
好了,现在数据实体已经准备就绪了,编译OK我们就可以继续了。
新建一个WEB项目或者WIN项目,为项目添加DataQuicker2和实体项目的引用,并在项目配置文件中设置数据库连接字符串。
如下
2 <add name="Default" providerName="System.Data.SqlClient" connectionString="Data Source=.\SQLEXPRESS; Initial Catalog=Dq2Sample;Integrated Security=SSPI"/>
3</connectionStrings>
4如果需要使用DQ2的日志功能,还需要配置如下代码
5<configSections>
6 <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
7</configSections>
8<log4net>
9 <root>
10 <level value="ALL" />
11 </root>
12 <logger name="DataQuicker2">
13 <level value="ALL" />
14 <appender-ref ref="RollingLogFileAppender" />
15 </logger>
16 <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
17 <param name="File" value="ExceptionLog\" />
18 <param name="AppendToFile" value="true" />
19 <param name="MaxSizeRollBackups" value="10" />
20 <param name="StaticLogFileName" value="false" />
21 <param name="DatePattern" value="yyyyMMdd".log"" />
22 <param name="RollingStyle" value="Date" />
23 <layout type="log4net.Layout.PatternLayout">
24 <param name="ConversionPattern" value="%d [%t] %-5p %c [%x] - %m%n%n" />
25 </layout>
26 </appender>
27</log4net>
28
这样就完全准备就续了。下面我们就可以开始领会DQ2为我们代来的好处了。我就以登陆系统为例吧,假设数据库的结构如下,
UserInfo表
UserID NvarChar(32) 实体层的ColumnValueType为GuidManaged
LoginID NvarChar(12)
Password NvarChar(40)
Role Int
Roles表
RoleID Int(数据库自编号) 实体层的ColumnValueType为DbAutoIncrease
RoleName NvarChar
用户注册页面后台代码
2private IDbConnection DBConn = DbFactory.CreateConnection("Default");
3protected void btnRegUser_Click(object sender, EventArgs e)
4{
5 if (DBConn.State != ConnectionState.Open) //判断数据库连接是否打开
6 DBConn.Open();
7 IDbTransaction tran = DBConn.BeginTransaction(); //设置事务处理
8 try
9 {
10 DQ2Demo.UserInfo user = new DQ2Demo.UserInfo();
11 user.LoginID.Value = txtLoginID.Text.ToLower();
12 user.GetRecordsCount(tran); //获得上面设定的登陆账号的数据行数 0.86新增
13 if (!user.IsExist) //这个属性平时是判断是否实例化成功,跟在GetRecordsCount后可以判断帐号是否已经存在
14 {
15 user.Password.Value = PassString(txtLoginID.Text.ToLower(),txtPassword.Text.ToLower());
16 int roleID = int.Parse(cbxRoleList.SelectedItem.Value);
17 DQ2Demo.Roles rose = new DataQuicker2.Demo.Roles(roleID, tran); //根据主键获得数据实体
18 user.Role.Value = rose; //这里使用了实体关联,稍后会进行介绍
19 user.Create(tran); //将新的用户信息数据提交到事务列表
20 //user.Updata(tran); 这里使用Updata就可以修改数据,但需要先获得数据实体成功
21 tran.Commit(); //将事务中的数据提交到数据库
22 Response.Write(@"<b>注册成功了</b>");
23 this.BindGrid();
24 }
25 else
26 Response.Write(@"<font color=red>用户名称重复</font>");
27 }
28 catch
29 {
30 tran.Rollback();
31 Response.Write(@"<b>注册失败了</b>");
32 }
33 finally
34 {
35 DBConn.Close();
36 }
37}
38
这里涉及到了数据库的新增,修改和通过带参数的实体构造函数来实现数据实体;下面我们继续介绍如和删除实体数据和第二种实例化实体的方发,我会在代码里面注明的。还是用上面假设的数据库,就用一个简单的用户管理来说明吧:)
2{
3 if (DBConn.State != ConnectionState.Open)
4 DBConn.Open();
5 IDbTransaction tran = DBConn.BeginTransaction();
6 string UserID = gridView.Rows[e.RowIndex].Cells[1].Text; //这里的GridView的第一列为用户登陆ID 不是主键,但根据上面的代码,可以知道这个字段的数值绝对是惟一的。
7 try
8 {
9 DQ2Demo.UserInfo user = new DataQuicker2.Demo.UserInfo();
10 user.UserName.Value = LoginID;
11 user.InitObject(tran); //这是实例化实体的第二种方法
12 if (user.IsExist) //判断实体是否实例化成功
13 {
14 user.Delete(tran);//删除用户信息,并提交到事务处理
15 tran.Commit();
16 Response.Write(@"<font color=red>用户删除成功</font>");
17 }
18 else
19 Response.Write(@"<font color=red>用户不存在</font>");
20 }
21 catch
22 {
23 tran.Rollback();
24 Response.Write(@"<font color=red>用户删除失败</font>");
25 }
26 finally
27 {
28 DBConn.Close();
29 }
30}
31
好了,删除也就这么回事了,简单吧。我现在来说明一下上面提到的实体关联。
其实,实体关联就是把两个表变为主从管理,从表中的关联字段保存主表中的数据的主键。在从表实体实例化的时候,主表会自动实例化,这样便可以很方便的通过从表获得主表的数据。要使用实体关联很简单,按照上面的数据结构,代码生成器的Role字段的代码应该是
2/// <summary>
3/// 设置/取得列对象Guid。<br />
4/// Set/Get column instance Guid.
5/// </summary>
6public Column<int> Role
7{
8 get
9 {
10 return this.role;
11 }
12 set
13 {
14 this.role = value;
15 }
16}
17
要使用实体关联,只需要把数据类型换成要关联的主表类就OK了如下
2/// <summary>
3/// 设置/取得列对象Guid。<br />
4/// Set/Get column instance Guid.
5/// </summary>
6public Column< Roles > Role
7{
8 get
9 {
10 return this.role;
11 }
12 set
13 {
14 this.role = value;
15 }
16}
17
使用的时候只需把关联的字段属性,比如所这里的Role当作是主表的实体类就好了。
注意事项:关联关系只能是单向的,比如说这里UserInfo类关联到了Roles类,如过Role类再关联到UserInfo类的话,就会造成死循环,后果就自己去尝试哈;
顺便提提我认为实体关联的好处:1,可以很方便的把一个数据表以及和他相关的数据全部提取出来,很大的提高了开发效率;2,好像更加面向对象:)
至于缺点吗:就是现在只能1对1的关联了,希望在以后的版本会实现一对多了。
好了,差不多了,第一次写BLOG,请大大们不要见笑,在介绍ObjectQuery的时候,还会涉及到实体类的其他方法。
Demo项目只是为演示DQ2,所以没有做过多的处理,将就看哈