让我用一个例子来解释一下。假设您正在使用经典的 SQL 方法实现应用程序。您打开记录集、更改数据并提交它。
伪代码:
trx = connection.CreateTransaction();
query = connection.CreateQuery("Select * from Employee where id = empid");
resultset = query.Run();
resultset.SetValue("Address_Street", "Bahnhofstrasse");
resultset.SetValue("Address_City", "Zürich");
trx.Commit();
使用 NHibernate,它看起来像这样:
emp = session.Get<Employee>(empid);
// persistence ignorant 'logic'
emp.Address.Street = "Bahnhofstrasse";
emp.Address.City = "Zürich";
session.Commit();
Persistence Ignorance 意味着业务逻辑本身不知道持久性。 或者换句话说,持久性与逻辑是分开的。这使得它更加可重用。
将“逻辑”移至可重用方法:
void MoveToZuerichBahnhofstrasse(Employee emp)
{
// doesn't have anything to do with persistence
emp.Address.Street = "Bahnhofstrasse";
emp.Address.City = "Zürich";
}
尝试使用结果集编写这样的方法,您就会知道什么是持久性无知。
如果你不相信,看看单元测试会有多简单,因为与持久性相关的东西没有任何依赖关系:
Employee emp = new Employee();
MovingService.MoveToZuerichBahnhofstreasse(emp);
Assert.AreEqual("Bahnhofstrasse", emp.Address.Street);
Assert.AreEqual("Zürich", emp.Address.City);
DDD 是不同的东西。在那里你首先建立你的领域模型(类模型)并根据它创建数据库设计。使用 NH,这非常简单,因为 - 由于对持久性的无知 - 您可以在拥有(确定的)数据库模型之前编写和单元测试模型和逻辑。
测试:我们通过创建实体实例、将其存储到数据库、取回并进行比较来测试映射。这是通过大量反射自动完成的。但你不需要走那么远。尝试存储实体时会出现大多数典型错误。
您可以对查询执行相同的操作。复杂的查询值得测试。如果查询完全被编译,那将是最有趣的。您甚至不需要任何数据。
对于数据库集成测试,我们使用Sqlite。这是相当快的。 NH 使用 SchemaExport 动态生成内存数据库(在每次测试之前)。