我正在工作的当前系统使用Castle Activerecord来提供域对象和数据库之间的ORM(对象关系映射)。这很好,大多数情况下都能正常工作!
问题出现在Castle Activerecord对异步执行的支持上,更具体地说是管理对象所属的会话的SessionScope。长话短说,会发生糟糕的事情!
因此,我们正在寻找一种简单的方式来自动(思考“自动魔法”)将域对象(知道存在DB并且关心它)转换为DTO对象(不知道DB的存在,也不关心会话、映射属性或所有ORM相关的事项)。
有人有建议吗?起初我正在寻找一个基本的一对一对象映射。域对象Person将被映射到PersonDTO。我不想手动完成这个过程,因为这太浪费时间了。
显然,反射会让人想到,但我希望有些更好的IT知识可以提供更“酷”的建议。
哦,我正在使用C#,ORM对象如前所述是由Castle ActiveRecord映射的。
示例代码:
根据@ajmastrean的请求,我已经链接到一个我(糟糕地)模拟的示例。该示例包括捕获表单、捕获表单控制器、域对象、activerecord 存储库和一个异步助手。它稍微有点大(3MB),因为我包括了运行所需的ActiveRecored dll文件。您需要在本地机器上创建一个名为ActiveRecordAsync的数据库,或者只需更改.config文件。
示例的基本详情:
捕获表单
捕获表单引用了控制器
private CompanyCaptureController MyController { get; set; }
在表单的初始化过程中,它会调用MyController.Load()方法。 private void InitForm () { MyController = new CompanyCaptureController(this); MyController.Load(); } 这将返回到一个名为LoadComplete()的方法。
public void LoadCompleted (Company loadCompany)
{
_context.Post(delegate
{
CurrentItem = loadCompany;
bindingSource.DataSource = CurrentItem;
bindingSource.ResetCurrentItem();
//TOTO: This line will thow the exception since the session scope used to fetch loadCompany is now gone.
grdEmployees.DataSource = loadCompany.Employees;
}, null);
}
}
这是“坏东西”发生的地方,因为我们使用了设置为延迟加载的Company子列表。
控制器
控制器有一个Load方法,该方法从表单中调用,然后调用异步帮助程序异步调用LoadCompany方法,然后返回到Capture表单的LoadComplete方法。
public void Load ()
{
new AsyncListLoad<Company>().BeginLoad(LoadCompany, Form.LoadCompleted);
}
LoadCompany()方法仅利用存储库查找已知公司。
public Company LoadCompany()
{
return ActiveRecordRepository<Company>.Find(Setup.company.Identifier);
}
这个例子的其余部分比较通用,它有两个继承自基类的领域类,一个安装文件以插入一些数据,并且还有一个仓库来提供 ActiveRecordMediator 的功能。