使用流畅的nhibernate进行事务和删除

时间:2010-05-19 23:16:21

标签: nhibernate

我开始玩(流利)nHibernate,我想知道是否有人可以提供以下帮助。我确定这是一个完全没有问题的人。

我想这样做:

   delete from TABX where name = 'abc'

其中表TABX定义为:

   ID int
   name varchar(32)
   ...

我根据互联网样本构建代码:

 using (ITransaction transaction = session.BeginTransaction())
                {
                    IQuery query = session.CreateQuery("FROM TABX WHERE name = :uid")
                        .SetString("uid", "abc");
                    session.Delete(query.List<Person>()[0]);
                    transaction.Commit();
                }

但是,它产生了两个查询(一个选择和一个删除)。我想在单个语句中执行此操作,就像在我的原始SQL中一样。这样做的正确方法是什么?

另外,我注意到在互联网上的大多数样本中,人们总是将所有查询都包装在交易中。这是为什么?如果我只运行一个声明,那似乎有点矫枉过正。人们往往只是盲目地剪切和粘贴,还是有其他原因?例如,在我上面的查询中,如果我管理它从两个查询到一个查询,我应该能够删除开始/提交事务,不是吗?

如果重要的话,我正在使用PostgreSQL进行实验。

3 个答案:

答案 0 :(得分:2)

您的第一个查询来自query.List<Person>()

您的实际删除声明来自session.Delete(...)

通常,当您只处理一个对象时,您将使用Load()或Get()。

Session.Load(type, id)将为您创建对象,而无需在数据库中查找它。但是,只要您访问其中一个对象的属性,它就会为对象提供水合作用。

Session.Get(type, id)实际上会为您查找数据。

就事务而言,这是一篇很好的文章,解释了为什么用事务包装所有nHibernate查询是好的。

http://nhprof.com/Learn/Alerts/DoNotUseImplicitTransactions

答案 1 :(得分:2)

您可以使用以下代码一步完成删除:

session.CreateQuery("DELETE TABX WHERE name = :uid")
       .SetString("uid", "abc")
       .ExecuteUpdate();

但是,通过这种方式,您可以避免事件侦听器调用(它只是映射到一个简单的SQL调用),缓存更新等。

答案 2 :(得分:0)

在NHibernate中,我注意到最常见的是用你看到的两个查询进行删除。我相信这是预期的行为。绕过它的唯一方法是使用缓存,然后第一个查询可以从缓存中加载,如果它恰好早先运行。

至于在事务中包装所有内容:在大多数数据库中,事务是隐式的,因为每个查询都是如此。显式事务只是保证数据不会在您操作中间被更改。