一般来说,有两种方法可以执行更新。一种是基于会话的,第二种是由 DML 表示的。
事务性持久实例(即,由 ISession 加载、保存、创建或查询的对象)可以由应用程序操作,并且在刷新 ISession 时,对持久状态的任何更改都将保持不变(本章稍后讨论)。所以最直接的更新对象状态的方法是 Load() 它,然后直接操作它,同时 ISession 是打开的...
因此,在我们的例子中,我们可以使用任何类型的查询将实体(Criteria、QueryOver、Query)加载到会话中。这意味着,不需要 HQL。
然后,所有对象都将在服务器/应用程序层 (C#) 上更新,然后在刷新会话后。所有更改都将保留。
这种方法需要大量后台处理(从 SQL 选择创建实体...创建 UPDATE 语句...)但对于 NHiberante/ORM 来说非常原生
using (ISession session = SessionFactory.OpenSession())
{
var criteria = session.CreateCriteria<T>();
// I. use criteria to find what should be changed
foreach (var cri in lstCriterios)
{
criterio.Add(cri);
}
// II. load the searched
var list = session.List<T>();
// III. update entities in runtime
foreach(var entity in list)
{
entity.Property1 = newValue1;
entity.Property2 = newValue2;
...
}
// IV. UPDATE == flush
session.Flush();
}
如前所述,自动和透明的对象/关系映射与对象状态的管理有关。这意味着对象状态在内存中可用,因此直接在数据库中操作(使用 SQL 数据操作语言 (DML) 语句:INSERT、UPDATE、DELETE)数据不会影响内存中的状态。然而,NHibernate 提供了用于批量 SQL 样式 DML 语句执行的方法,这些语句通过 Hibernate 查询语言 (HQL) 执行...
在这种情况下,我们确实可以访问最有效的 UPDATE - 直接在数据库服务器上执行,无需任何实体加载。见例子:
ISession session = sessionFactory.OpenSession();
ITransaction tx = session.BeginTransaction();
string hqlUpdate = "update Customer c set c.name = :newName where c.name = :oldName";
// or string hqlUpdate = "update Customer set name = :newName where name = :oldName";
int updatedEntities = s.CreateQuery( hqlUpdate )
.SetString( "newName", newName )
.SetString( "oldName", oldName )
.ExecuteUpdate();
tx.Commit();
session.Close();
虽然这种方法给我们带来了出色的性能,但它基于 HQL(与上述要求相反)...
总结:使用 NHibernate,我们可以使用强大的查询而不使用 HQL 将数据加载到会话中,在 C# 中操作它们,一个一个地持久化更改......或者我们可以使用 HQL 创建一个 DML 语句,并直接在 UPDATE 上执行服务器
另请参阅:NHibernate – Executable DML Ayende