最近因为公司项目的需要,使用了Eunge的DataQuicker2这个数据持久层,感觉确实像Eunge所说的代码简洁、唯美,性能很好,可惜现在没有帮助,所以记下对DQ2的使用的个人理解。有不足之处,还希望大家多多提出。本文是我第一次写BLOG,心情比较激动。J
DQ2提供了一个实体生成器,使用很简单,就不介绍软件的使用了,这里讲一下使用的技巧以及注意事项;
一:注意事项,一共有两点:
1:代码生成目录必须存在;2:命名空间用程序集的命名空间加上文件夹的形式,在介绍DQL的时候再说明原因;
二:使用的小技巧;打开代码生成器目录的CodeGenerator.exe.config文件,修改对应的
命名空间,连接字符串,输出目录的默认值,以后使用的时候便可少些输入;
好了,入正题了。在用代码生成器,创建好了实体类以后,就可以用VS建立一个类库,然后导入刚才创建好的实体代码,添加DataQuicker2的引用。就基本OK了,这里也两点需要要注意的问题
1、在实体类的Bind()方法中,请先确定
this.BindPrimaryKey(this.ideaID, ColumnValueType.GuidManaged);中的ColumnValueType是否为预期的模式,在目前的0.87版中有以下四项可选项
// 非DataQuicker2托管的。
Unmanaged
// 数据库自增长字段。
DbAutoIncrease
// DataQuicker2托管的INT值填充,字段类型一般应为INT类型,也可以为字符串类型,但是性能损失很大,并且不利于索引。
IntManaged
//DataQuicker2托管的GUID值填充,字段类型一般应为Varchar(32)。
GuidManaged 
2、确定生成的实体属性与系统的类名,保留字的名字不同;本文结束时,我会附上修改过的代码模板,下载后覆盖原来的文件就没有这个问题了,你也可以自行修改为你习惯的模式。
好了,现在数据实体已经准备就绪了,编译OK我们就可以继续了。
新建一个WEB项目或者WIN项目,为项目添加DataQuicker2和实体项目的引用,并在项目配置文件中设置数据库连接字符串。
如下
<connectionStrings>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
用户注册页面后台代码
//其实这里的连接名称为Default时,可以不显示的声明IDBConnection,因为使用隐式的默认连接不支持0.87新增的GetDataReader,所以这里使用显示的连接2
private IDbConnection DBConn = DbFactory.CreateConnection("Default");3
protected void btnRegUser_Click(object sender, EventArgs e)4
{5
if (DBConn.State != ConnectionState.Open) //判断数据库连接是否打开6
DBConn.Open();7
IDbTransaction tran = DBConn.BeginTransaction(); //设置事务处理8
try9
{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
else26
Response.Write(@"<font color=red>用户名称重复</font>");27
}28
catch29
{30
tran.Rollback();31
Response.Write(@"<b>注册失败了</b>");32
}33
finally34
{35
DBConn.Close();36
}37
}38

这里涉及到了数据库的新增,修改和通过带参数的实体构造函数来实现数据实体;下面我们继续介绍如和删除实体数据和第二种实例化实体的方发,我会在代码里面注明的。还是用上面假设的数据库,就用一个简单的用户管理来说明吧:)
protected void gridView_RowDeleting(object sender, GridViewDeleteEventArgs e)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
try8
{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
else19
Response.Write(@"<font color=red>用户不存在</font>");20
} 21
catch22
{23
tran.Rollback();24
Response.Write(@"<font color=red>用户删除失败</font>");25
}26
finally27
{28
DBConn.Close();29
}30
}31

好了,删除也就这么回事了,简单吧。我现在来说明一下上面提到的实体关联。
其实,实体关联就是把两个表变为主从管理,从表中的关联字段保存主表中的数据的主键。在从表实体实例化的时候,主表会自动实例化,这样便可以很方便的通过从表获得主表的数据。要使用实体关联很简单,按照上面的数据结构,代码生成器的Role字段的代码应该是
private Column<int> role = new Column<int>();2
/// <summary>3
/// 设置/取得列对象Guid。<br />4
/// Set/Get column instance Guid.5
/// </summary>6
public Column<int> Role7
{8
get9
{10
return this.role;11
}12
set13
{14
this.role = value;15
}16
}17

要使用实体关联,只需要把数据类型换成要关联的主表类就OK了如下
private Column<Roles> role = new Column< Roles >();2
/// <summary>3
/// 设置/取得列对象Guid。<br />4
/// Set/Get column instance Guid.5
/// </summary>6
public Column< Roles > Role7
{8
get9
{10
return this.role;11
}12
set13
{14
this.role = value;15
}16
}17

使用的时候只需把关联的字段属性,比如所这里的Role当作是主表的实体类就好了。
注意事项:关联关系只能是单向的,比如说这里UserInfo类关联到了Roles类,如过Role类再关联到UserInfo类的话,就会造成死循环,后果就自己去尝试哈;
顺便提提我认为实体关联的好处:1,可以很方便的把一个数据表以及和他相关的数据全部提取出来,很大的提高了开发效率;2,好像更加面向对象:)
至于缺点吗:就是现在只能1对1的关联了,希望在以后的版本会实现一对多了。
好了,差不多了,第一次写BLOG,请大大们不要见笑,在介绍ObjectQuery的时候,还会涉及到实体类的其他方法。
Demo项目只是为演示DQ2,所以没有做过多的处理,将就看哈


浙公网安备 33010602011771号