我想在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;
}
}
答案 0 :(得分:1)
通常,有两种方法可以执行Update。一个是基于会话的,第二个是由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提供了通过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