在NHibernate中更新没有HQL模式的方法

本文关键字:HQL 模式 方法 NHibernate 更新 | 更新日期: 2023-09-27 18:25:25

我想在NHibernate中制作一个带有限制的Update方法(where子句),但我不想使用HQL模式。

例如,我的SQL查询:

"update NFE set SEFAZ_STATUS_DATA=@SEFAZ_STATUS_DATA,MENSAGEM_ERRO=@MENSAGEM_ERRO"

我怎么能不用HQL?

这行得通吗?

public virtual T Alterar(List<ICriterion> lstCriterios, T entity)
{
    try
    {
        using (ISession session = SessionFactory.OpenSession())
        {
            ICriteria criterio = session.CreateCriteria(typeof(T));
            foreach (ICriterion cri in lstCriterios)
            {
                criterio.Add(cri);
            }
            session.Update(entity);
            return entity;
        }
    }
    catch (Exception ex)
    {
        throw ex;
    }
}

在NHibernate中更新没有HQL模式的方法

通常,有两种方法可以执行Update。一种是基于会话的,另一种是由DML表示的。

9.4.1.在同一会话中更新

事务性持久实例(即ISession加载、保存、创建或查询的对象)可以由应用程序操作,并且当ISession被刷新时,对持久状态的任何更改都将被持久化(本章稍后讨论)。因此,更新对象状态最简单的方法是在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();
}

13.3 DML式操作

如前所述,自动和透明的对象/关系映射涉及对象状态的管理。这意味着对象状态在内存中可用,因此直接在数据库中操作(使用SQL数据操作语言(DML)语句:INSERT、UPDATE、DELETE)数据不会影响内存中的状态。然而,NHibernate提供了通过Hibernate查询语言(HQL)执行批量SQL风格DML语句的方法。。。

在这种情况下,我们可以访问最有效的UPDATE——直接在DB服务器上执行,而不需要任何实体加载。参见示例:

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–Ayende 的可执行DML