2

我们正在将一个项目从普通的 MySQL 查询重构为使用 NHibernate。在 MySQL 连接器中有返回受影响行的ExecuteNonQuery函数。所以

int RowsDeleted = ExecuteNonQuery("DELETE FROM `table` WHERE ...");

会告诉我有多少行被有效删除。

我怎样才能用 NHibernate 达到同样的效果?到目前为止,我可以看到这是不可能的Session.Delete(query);

我目前的解决方法是首先加载所有即将被删除的对象并一个接一个地删除它们,每次删除时增加一个计数器。但我可以假设这会降低性能。

4

1 回答 1

2

如果您不介意 nHibernate 将为每一行创建删除语句,并且可能为孤儿和/或其他关系创建附加语句,您可以使用session.Delete.

为了获得更好的性能,我建议进行批量删除(参见下面的示例)。

会话.删除

如果您使用 session.Delete 删除许多对象,nHibernate 会确保保留完整性,如果需要,它会将所有内容加载到会话中。因此,没有真正的理由来计算您的对象或有一种方法来检索已删除的对象数量,因为您只需在运行删除之前进行查询以确定将受到影响的对象数量......

以下语句将按 id 删除所有 post 类型的实体。select 语句将仅查询数据库的 ID,因此它实际上非常高效......

var idList = session.Query<Post>().Select(p => p.Id).ToList<int>();
session.Delete(string.Format("from Post where Id in ({0})", string.Join(",", idList.ToArray())));

删除的对象数将等于列表中的 Id 数...

这实际上是相同的(就 nHibernate 将针对您的数据库触发的查询而言),就好像您将query<T>遍历结果并一一删除它们一样......

批量删除

您可以使用它session.CreateSqlQuery来运行本机 SQL 命令。它还允许您拥有输入和输出参数。

如您所料,以下语句将简单地从表中删除所有内容

session.CreateSQLQuery(@"Delete from MyTableName");

要检索删除的行数,我们将使用普通的 TSQL@@ROWCOUNT变量并通过 select 输出它。要检索选定的行数,我们必须在创建的查询中添加一个输出参数,AddScalar然后UniqueResult简单地返回整数:

var rowsAffected = session.CreateSQLQuery(@"
        Delete from MyTableName; 
        Select @@ROWCOUNT as NumberOfRows")
    .AddScalar("NumberOfRows", NHibernateUtil.Int32)
    .UniqueResult();

要传递输入变量,您可以使用.SetParameter(<name>,<value>)

var rowsAffected = session.CreateSQLQuery(@"
        DELETE from MyTableName where ColumnName = :val; 
        select @@ROWCOUNT NumberOfRows;")
     .AddScalar("NumberOfRows", NHibernateUtil.Int32)
     .SetParameter("val", 1)
     .UniqueResult();

我对 MySQL 不太满意,我写的例子是针对 MSSQL,我认为在 MySQL 中@@ROWCOUNT相当于SELECT ROW_COUNT();

于 2013-10-03T09:30:50.410 回答