NHibernate OR EES ,不能比较的比较
或许EES 与 NH 根本就没有可比性,一个是业界久负盛名,一个是发育不良的幼儿
从老赵的BLOG里面和其他的地方了解到了一些NHibernate的处理方式,也没有深入去学习,当然,不是不想去学习,只是时间不允许去深入学习,首先要填饱肚子嘛。
关于EES的ORM,代码组织上面已经介绍过了,处理过程和很多细节方面没有作介绍, 结合老赵的点评,把自己的EES ORM 部分介绍大致的介绍一下。
EES的ORM,数据模型采用的也是贫血型的领域。
典型代码 public class Order { string custCode; public virtual string CustCode { get{retrun custCode;} set{custCode=value;}} Customer customer; public virtual Customer Customer { get{retrun customer;} set{customer=value;} } DataCollection<OrderDTL> itemCollection; public virtual DataCollection<OrderDTL> ItemCollection { get{retun itemCollection;} set{itemCollction=value;} } }
1、对于延迟加载的处理:老赵关于延迟的原文
延迟加载所用的机制与赵介绍的类似,不过,用的不是Func<>类似的处理方式,而是直接用IL写的。根据配置文件和一些条件动态生成代理类,如果需要延迟加载的,则生成延迟加载相关逻辑。如果延迟加载的,则代理类的示意代码如下:
public class DOrder : Order { bool __custCode; public override string TagNames { get { if(!__custCode) { __custCode=true; base.TagNames = "……加载部分逻辑"; } return base.TagNames; } set { __custCode=true; base.TagNames = value; } } }
D,代表是动态类,每个动态类都是在原来类的前面加上D
在生成延迟加载逻辑的同时,根据配置文件,还生成了校验逻辑,以后面的Interceptor的处理里面,再作介绍。
2、对virtual的处理:老赵的关于Virtual处理的原文
对于virtual的处理,与NH,有稍微的不同:在EES里面(老赵可以不用抱怨了,哈哈),与数据库映射的类,其实不仅仅是与数据库映射类,用还是不用virtual,是需要考虑的。
默认状态下工具生成的代码,public 的属性都是 有virtual 的。对于同步加载的字段和不需要校验的属性,可以去掉 virtual;反过来,如果是需要校验的,则必须加上。并且在使用的时候,需要注意使用属性,而不是字段,这一点,给编码过程中引入了一个出BUG的机率。
在数据类方面,virtual 除了上面常用的这两点,还有一个重要的一点:自动维护双向关系,如果不加virtual,则系统无法自动维护双向关系,也无法实现双向绑定和级联触发。
3、对集合的处理:老赵的关于自定义集合
关于自定义集合,真的很遗憾,EES 不支持自定义集合,特别是在数据加载的时候。
对于双向关系维护,框架是提供了。都在后台处理,从编码上看,通常不需要单独处理,与老赵的处理方式有一点点的差异。上面已经提过,必须要求 在属性前添加 virtual 。
DataCollection<OrderDTL> itemCollection; public virtual DataCollection<OrderDTL> ItemCollection { get{retun itemCollection;} set{itemCollction=value;} }
对于映射类和其他普通数据类,框架要求尽可能的从 EESObject 继承,对于集合类,尽可能的用 DataCollection 这个类。
这两个类都实现了同一个接口:ICascade
public interface ICascade { object Parent { get; set; } }
通过此接口实现数据的回溯。一个对象的父类,要么是一个集合要么是一个对象,有且只有一个父级。
在使用的时候可以通过强制转换来应用。在访问的时候,会在get里面会给Parent赋值。在生成动态类的时候,会根据public 和 virtual 以及 ICacscade 进行逻辑生成。
4、对于Interceptor的处理:老赵的关于Interceptor的处理
Interceptor 在EES框架里面,处于非常非常重要位置。但是在处理机制上面,与NH的距离还是不小的。介绍一下自己的处理方式,也希望大家能给出批评和建议。
在EES里,Interceptor主要提供了 前/后/包围 三种方式,主要应用在属性和函数上面,对于静态函数暂时不支持。使用要求与上面提到的一样,要求必须是public 并且添加 virtual 的。
对于属性的应用主要是 校验和延迟加载;对于函数的应用主要是事务/日志或其他的应用,可以自行扩展。
在EES 的BLL里面,或EES 提供的数据库相关逻辑里面,提供了一点常用的其他操作和处理过程。这一点,与框架的处理思想直接相关,每个人的想法都有所差异。
在BLService里,提供了类似于老赵的这一篇回复里处理机制,但他不是Interceptor,作用类似。
public class BLService<T> : IBLService<T>, ICloneable where T : global::EES.Common.Data.EESObject { public BLService(); protected IContext EESContext { get; } [Operation(ScopeOption.Required)] public virtual T Add(T t); [Operation(ScopeOption.Required)] public virtual DataCollection<T> AddAll(DataCollection<T> collection); [Operation(ScopeOption.Required)] protected virtual DataCollection<T> AddAllCore(DataCollection<T> collection, object state); [Operation(ScopeOption.Required)] protected virtual T AddCore(T t, object state); public object Clone(); [Operation(ScopeOption.Disabled)] public virtual int Count(params IClause[] clauses); [Operation(ScopeOption.Required)] public virtual T Delete(T t); [Operation(ScopeOption.Required)] public virtual DataCollection<T> DeleteAll(DataCollection<T> collection); [Operation(ScopeOption.Required)] protected virtual DataCollection<T> DeleteAllCore(DataCollection<T> collection, object state); [Operation(ScopeOption.Required)] protected virtual T DeleteCore(T t, object state); [Operation(ScopeOption.Required)] protected virtual object Execute(string commandText); [Operation(ScopeOption.Required)] protected virtual object Execute(string commandText, params KeyValuePair<string, object>[] parameters); [Operation(ScopeOption.Disabled)] public virtual DataCollection<T> Find(params IClause[] clauses); [Operation(ScopeOption.Disabled)] protected virtual DataCollection<D> FindCore<D>(params IClause[] clauses) where D : EESObject; [Operation(ScopeOption.Disabled)] protected virtual T FindId(params object[] primaryKeys); [Operation(ScopeOption.Disabled)] public virtual DataCollection<T> FindPage(int currentPage, int pageSize, params IClause[] clauses); [Operation(ScopeOption.Disabled)] protected virtual T FindPair(params KeyValuePair<string, object>[] properties); [Operation(ScopeOption.Disabled)] public object LoadProperty(EESObject obj, string propertyName); protected virtual void OnAdded(T t, object state); protected virtual void OnAdding(T t, object state); protected virtual void OnDeleted(T t, object state); protected virtual void OnDeleting(T t, object state); protected virtual void OnSaved(T t, object state); protected virtual void OnSaving(T t, object state); protected virtual void OnUpdated(T t, object state); protected virtual void OnUpdating(T t, object state); [Operation(ScopeOption.Required)] public virtual T Save(T t); [Operation(ScopeOption.Required)] public virtual DataCollection<T> SaveAll(DataCollection<T> collection); [Operation(ScopeOption.Required)] protected virtual DataCollection<T> SaveAllCore(DataCollection<T> collection, object state); [Operation(ScopeOption.Required)] protected virtual T SaveCore(T t, object state); [Operation(ScopeOption.Required)] public virtual T Update(T t); [Operation(ScopeOption.Required)] protected virtual T UpdateCore(T t, object state); }
没有别的,又是一大堆 virtual,我自己都有点无语了,不过这里的virtual 不是为了生成动态类,而是为了在派生类里面重写。
protected virtual void OnAdded(T t, object state); protected virtual void OnAdding(T t, object state); protected virtual void OnDeleted(T t, object state); protected virtual void OnDeleting(T t, object state); protected virtual void OnSaved(T t, object state); protected virtual void OnSaving(T t, object state); protected virtual void OnUpdated(T t, object state); protected virtual void OnUpdating(T t, object state);
这几个空函数,主要是为了在处理层次数据的时候使用。
对于上面的Order类,可以在保存完主订单后,再调用OrderDTLService 来保存 订单的明细,也可以在订单明细OnAdding里面,进行库存的核查。
关于与NH的对比,先写到这里,以后再慢慢的完善吧
还有很多与NH不相关的,但是属性框架一部分的内容,接下来,再介绍……