代码改变世界

实现完全脱离MySoft.Data引用的实体

2010-03-09 22:44 by Benking, ... 阅读, ... 评论, 收藏, 编辑

利用MySoft.Data组件中的 SourceList 类中的 ConvertTo 泛型方法可以将你的ORM实体转换成其他类型的实体,从而可实现应用层脱离对MySoft.Data的引用,达到数据库层与应用层完全解耦的目的。

要达到解耦的目的,首先需要建立一套和ORM实体对应的最简洁的实体。这里以Xpress中的MailOutbond为例,首先利用MySoft.Data实体生成工具,生成一个MailOutbond实体类(当然这个实体类非常复杂,直接依赖于MySoft.Data)。

若想在应用层不要依赖MySoft.Data(即不直接依赖MailOutbond实体类),势必我需创建一个与MailOutbond ORM实体对应的一个单纯的实体,下称“简洁实体”,比如取名叫:MailOutbondModel(里面除了一个一个的属性,没有其他任何内容)。

为了更好的约束ORM实体与简洁实体,可以用接口来对他们进行约束,同时应用层直接引用的也就是这个接口,如:IMailOutbond。因此,整个过程我们需要建立如下与实体相关的类与接口:

1、MailOutbond(ORM实体)

2、MailOutbondModel(单纯实体)

3、IMailOutbond(实体接口)

其中,MailOutbond 与 MailoutbondModel 都需要实现接口 IMailOutbond。

由于在解耦过程中,需要进行一系列的转换工作,如:

1、将 接口 转换为 实体

2、将 实体 转换为 接口

为了保持通用性以及便于管理,我们将这些转换方法以扩展的形式写在实体接口上。如果你的系统有若干个实体,建议在每个实体接口上面再包装一层,比如让这些实体接口都继承一个空接口,如:IEntity。继承这个空接口有很多好处,尤其是在做转换的时候,同时我们的转换扩展方法也需要扩展在这个空实体接口上,如:

 

01/// <summary>
02        /// 转换成实体
03        /// </summary>
04        /// <typeparam name="TEntity"></typeparam>
05        /// <param name="entity"></param>
06        /// <returns></returns>
07        public static TEntity ToEntity<TEntity>(thisDsJian.Interface.Model.IEntity entity)
08            where TEntity : MySoft.Data.Entity
09        {
10            return newMySoft.Data.SourceList<DsJian.Interface.Model.IEntity>(entity)
11                .ConvertTo<TEntity>()[0];
12        }
13 
14        /// <summary>
15        /// 转换成接口
16        /// </summary>
17        /// <typeparam name="TEntity"></typeparam>
18        /// <typeparam name="IEntity"></typeparam>
19        /// <param name="entity"></param>
20        /// <returns></returns>
21        public static IEntity ToIEntity<TEntity, IEntity>(thisMySoft.Data.Entity entity)
22            where IEntity : DsJian.Interface.Model.IEntity
23        {
24            return newMySoft.Data.SourceList<MySoft.Data.Entity>(entity).ConvertTo<TEntity, IEntity>()[0];
25        }

========================================

至此,准备工作都做好了,我们可以在具体数据库业务逻辑方法中用到这些转换,实现脱藕。

例如,我们插入一条 MailOutbond 数据,我们可以这样写:

 

1/// <summary>
2        /// 添加到邮件队列
3        /// </summary>
4        /// <param name="mail"></param>
5        public void AddMail(IMailOutbond mail)
6        {
7            repository.GetSession().Save<MailOutbond>(mail.ToEntity<MailOutbond>());
8        }

其中,GetSession() 方法是创建一个DbSession进行数据库操作。这里保存一条数据时,传入的是一个 IMailOutbond 接口对象,实际引用对象应该是从应用层创建的 MailOutbondModel 对象。

调用扩展方法 ToEntity<MailOutbond>() 即可将 MailOutbondModel 转换为对应的ORM实体对象,进行数据库插入工作。

又例如,我们从数据库获取所有待发邮件队列,可以这样实现:

 

01/// <summary>
02        /// 获取未发出 Mail
03        /// </summary>
04        /// <returns></returns>
05        public IList<IMailOutbond> GetUnSendList()
06        {
07            return repository.GetSession().From<MailOutbond>()
08                .Where(MailOutbond._.IsSend == false && MailOutbond._.RetryCount > 0)
09                .ToList().ConvertTo<MailOutBondModel, IMailOutbond>();
10        }

调用SourcesList的ConvertTo泛型方法,可以将ORM实体转换为一个简洁实体(MailOutBondModel),并已接口的形式返回。

如果所有的数据库业务操作都遵守这样的编写规范,我们的解耦工作也就顺利完成了。

更多细节,可以参考我的开源项目 Xpress

       参考:MySoft.Data