业务实体加载模式
我正在工作的项目正在使用n层体系结构。我们的图层如下:
- 资料存取
- 商业逻辑
- 商业实体
- 介绍
业务逻辑调用到数据访问层,表示层调用到业务逻辑层,并且所有实体都引用业务实体。
我们的业务实体实质上与我们的数据模型1-1相匹配。对于每个表,我们都有一个类。最初在设计框架时,没有考虑管理主从关系或者子与父母之间的关系。因此,所有业务逻辑,数据访问和业务实体都仅引用了数据库中的单个表。一旦开始开发应用程序,很快就会发现,对象模型中没有这些关系会严重损害我们。
所有层(包括数据库)都是从内部元数据数据库生成的,我们用它来驱动我们自己的代码生成器。
问题是在实体中加载或者延迟加载关系的最佳方法是什么。例如,假设我们有一个人员类,该人员类与地址表具有主子关系。这在业务实体中显示为Person对象上Addresses的集合属性。如果我们具有一对一的关系,那么它将显示为单个实体属性。填充和保存关系对象的最佳方法是什么?我们的业务实体不了解业务逻辑层,因此在调用属性时无法在内部完成。
我敢肯定有某种标准的方法可以做到这一点。有什么建议?
同样,一个警告是,DataAcess层使用反射来构建我们的实体。存储过程基于一个表返回一个结果selt,然后使用反射,通过将属性名称与列名称匹配来填充业务对象。因此,进行联接将很困难。
解决方案
我们使用什么语言?我们所描述的正是Entity Framework在.Net中的功能。但是我们没有分享使用的语言,并且我假设我们不想重写任何数据层。
我过去使用的一种方法是使容器类型足够聪明,以获取所需的对象。例如:
public class Relation<T> { private T _value; private void FetchData() { if( LoadData != null ) { LoadDataEventArgs args = new LoadDataEventArgs(typeof(T), /* magic to get correct object */); LoadData(this, args); _value = (T)args.Value; } } public event EventHandler<LoadDataEventArgs> LoadData; public T Value { get { if( _value == default(T) ) FetchData(); return _value; } set { /* Do magic here. */ } } }
然后在实体上声明它,例如:
[RelationCriteria("ID", EqualsMyProperty="AddressID")] public Relation<Address> Address { get; set; }
并且取决于声明Address属性的类型的加载器,以将处理程序添加到LoadData事件。
一个类似的类实现IList来给我们一对多的关系。
我强烈建议我们阅读Fowler的《企业体系结构模式》一书。他很好地概述了解决这类问题的几种不同方法,包括实体关系。
更具说服力的项目之一是工作单元模式,它基本上是一个收集器,它观察在实体上执行的操作,完成操作后,它将批处理适当的数据库调用,并向数据库发出请求。数据库。这种模式是NHibernate使用的中心概念之一,它使用实现IDisposable的对象来表示"工作"的结束。这使我们可以将使用中的操作包装起来,并让工作单元为我们处理这些操作。
编辑:添加信息
这是工作单元基本类结构的链接……这并不是世界上最令人兴奋的事情。 Fowler在他的书中提供了更多细节,我们可以在此处查看其中的一些细节。我们还可以将NHibernate中的Session对象视为可能的实现(我能够找到ISession接口...不确定实现在哪里)
希望这可以帮助。