利用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。继承这个空接口有很多好处,尤其是在做转换的时候,同时我们的转换扩展方法也需要扩展在这个空实体接口上,如:
04 | /// <typeparam name="TEntity"></typeparam> |
05 | /// <param name="entity"></param> |
06 | /// <returns></returns> |
07 | public static TEntity ToEntity<TEntity>( this DsJian.Interface.Model.IEntity entity) |
08 | where TEntity : MySoft.Data.Entity |
10 | return new MySoft.Data.SourceList<DsJian.Interface.Model.IEntity>(entity) |
11 | .ConvertTo<TEntity>()[0]; |
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>( this MySoft.Data.Entity entity) |
22 | where IEntity : DsJian.Interface.Model.IEntity |
24 | return new MySoft.Data.SourceList<MySoft.Data.Entity>(entity).ConvertTo<TEntity, IEntity>()[0]; |
========================================
至此,准备工作都做好了,我们可以在具体数据库业务逻辑方法中用到这些转换,实现脱藕。
例如,我们插入一条 MailOutbond 数据,我们可以这样写:
4 | /// <param name="mail"></param> |
5 | public void AddMail(IMailOutbond mail) |
7 | repository.GetSession().Save<MailOutbond>(mail.ToEntity<MailOutbond>()); |
其中,GetSession() 方法是创建一个DbSession进行数据库操作。这里保存一条数据时,传入的是一个 IMailOutbond 接口对象,实际引用对象应该是从应用层创建的 MailOutbondModel 对象。
调用扩展方法 ToEntity<MailOutbond>() 即可将 MailOutbondModel 转换为对应的ORM实体对象,进行数据库插入工作。
又例如,我们从数据库获取所有待发邮件队列,可以这样实现:
04 | /// <returns></returns> |
05 | public IList<IMailOutbond> GetUnSendList() |
07 | return repository.GetSession().From<MailOutbond>() |
08 | .Where(MailOutbond._.IsSend == false && MailOutbond._.RetryCount > 0) |
09 | .ToList().ConvertTo<MailOutBondModel, IMailOutbond>(); |
调用SourcesList的ConvertTo泛型方法,可以将ORM实体转换为一个简洁实体(MailOutBondModel),并已接口的形式返回。
如果所有的数据库业务操作都遵守这样的编写规范,我们的解耦工作也就顺利完成了。
更多细节,可以参考我的开源项目 Xpress。
参考:MySoft.Data