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

时间:2014-10-01 17:44:40

标签: c# nhibernate fluent-nhibernate hql

我想在NHibernate中使用限制(where子句)创建一个Update方法,但我不想做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;
    }
}

1 个答案:

答案 0 :(得分:1)

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

9.4.1. Updating in the same ISession

  

事务持久化实例(即,由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();
}

13.3. DML-style operations

  

如前所述,自动和透明的对象/关系映射与对象状态的管理有关。这意味着对象状态在内存中可用,因此直接在数据库中操作(使用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上执行服务器

另见:Ayende的NHibernate – Executable DML