题
我正在做的项目正在使用n层架构。我们的层如下:
- 数据存取
- 商业逻辑
- 商业实体
- 推介会
业务逻辑向下调用数据访问层,表示层向下调用业务逻辑层,并且业务实体被它们全部引用。
我们的业务实体本质上与我们的数据模型1-1匹配。对于每张桌子,我们都有一个班级。最初设计框架时,没有考虑管理主从关系或子父关系。因此,所有业务逻辑、数据访问和业务实体仅引用数据库中的单个表。一旦我们开始开发应用程序,我们很快就会发现,在我们的对象模型中没有这些关系对我们造成了严重伤害。
您的所有层(包括数据库)都是从内部元数据数据库生成的,我们用它来驱动我们自己开发的代码生成器。
问题是加载或延迟加载实体中关系的最佳方法是什么。例如,假设我们有一个与地址表具有主子关系的人员类。这在业务实体中显示为 Person 对象上的 Addresses 的集合属性。如果我们有一对一的关系,那么这将显示为单个实体属性。填充和保存关系对象的最佳方法是什么?我们的业务实体不了解业务逻辑层,因此在调用属性 get 时无法在内部完成。
我确信有某种标准模式可以做到这一点。有什么建议么?
另外,需要注意的是 DataAcess 层使用反射来构建我们的实体。存储过程基于一张表返回一个结果集,并且使用反射,我们通过将属性名称与列名称相匹配来填充我们的业务对象。所以做连接会很困难。
解决方案
我强烈推荐看看福勒的 企业架构模式 书。他很好地概述了解决此类问题的几种不同方法,包括实体关系。
更引人注目的项目之一是工作单元模式,它基本上是一个收集器,它观察对实体执行的操作,一旦完成操作,它就会批处理适当的数据库调用,并向数据库。该模式是使用的核心概念之一 NHibernate, ,它使用一个实现 IDisposable 的对象来表示“工作”的结束。这允许您将操作包装在 using 中,并让工作单元为您处理操作。
编辑:附加信息
这 是到工作单元的基本类结构的链接......这并不是世界上最令人兴奋的事情。福勒在他的书中提供了更多细节,其中一些你可以看到 这里. 。您还可以将 NHibernate 中的 Session 对象视为可能的实现(我能够追踪到 会话 接口...不确定实现在哪里)
希望这可以帮助。
其他提示
我过去使用的一种方法是使容器类型足够智能以获取所需的对象。例如:
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 来为您提供一对多关系。
您使用什么语言?您所描述的正是实体框架在.Net 中所做的事情。但是您没有分享您使用的语言,我假设您不想重写任何数据层。