代码之家  ›  专栏  ›  技术社区  ›  Erik Öjebo

使用nhibernate删除表中所有行的最佳方法?

  •  34
  • Erik Öjebo  · 技术社区  · 16 年前

    为了保持集成测试的独立性,我删除了所有旧数据,并在每次测试之前插入新的测试数据。有没有比简单地查询所有实体并逐个删除它们更好的方法?

    我考虑编写一个运行“delete from”的存储过程 数据表名 对于要清除的每个表。这应该会快一点,但最好不要进行SQL查询或通过NH调用SP。

    我在用香草NHIBERNATE和LINQ来NHIBERNATE。我认为Castle活动记录类似于foo.deleteall(),但我不想为此项目使用活动记录。

    有什么想法吗?

    谢谢/埃里克

    更新:

    自从这个问题被问到和回答之后,NHibernate团队已经取得了进展。正如Ayende在 this blog post ,现在可以直接执行DML查询,而无需nhibernate获取任何实体。

    要删除所有foo对象,可以这样做:

    using (ISession session = ...)
    using (ITransaction transaction = session.BeginTransaction())
    {
        session.CreateQuery("delete Foo f").ExecuteUpdate();
    
        transaction.Commit();
    }
    

    此查询将生成以下SQL:

    delete from Foo
    

    这可能比先获取实体然后删除实体快得多。但是要小心,因为像这样的查询不会影响1级缓存。

    3 回复  |  直到 7 年前
        1
  •  32
  •   Frederik Gheysels    16 年前

    在单元测试的拆卸过程中,我主要这样做:

    using( ISession s = ... )
    {
       s.Delete ("from Object o");
       s.Flush();
    }
    

    这将删除所有实体。 如果要删除一个特定实体的所有实例,可以执行以下操作:

    using( ISession s = .... )
    {
        s.Delete ("from MyEntityName e");
        s.Flush();
    }
    

    当然,这种方法有一个缺点,那就是nhibernate将首先获取实体,然后再删除它们。

        2
  •  11
  •   Ilya Serbis    12 年前

    我使用流畅的nhibernate属性,所以我修改了一些代码,以避免硬编码表名。

    private static void CleanUpTable<T>(ISessionFactory sessionFactory)
    {
        var metadata = sessionFactory.GetClassMetadata(typeof(T)) as NHibernate.Persister.Entity.AbstractEntityPersister;
        string table = metadata.TableName;
    
        using (ISession session = sessionFactory.OpenSession())
        {
            using (var transaction = session.BeginTransaction())
            {
                string deleteAll = string.Format("DELETE FROM \"{0}\"", table);
                session.CreateSQLQuery(deleteAll).ExecuteUpdate();
    
                transaction.Commit();
            }
        }
    }
    

    使用

    CleanUpTable<Person>(sessionFactory);
    
        3
  •  3
  •   Sÿl    7 年前

    使用NHibernate 5.0,您现在可以简单地执行以下操作:

    session.Query<Foo>().Delete();
    

    文档:

        //
        // Summary:
        //     Delete all entities selected by the specified query. The delete operation is
        //     performed in the database without reading the entities out of it.
        //
        // Parameters:
        //   source:
        //     The query matching the entities to delete.
        //
        // Type parameters:
        //   TSource:
        //     The type of the elements of source.
        //
        // Returns:
        //     The number of deleted entities.
        public static int Delete<TSource>(this IQueryable<TSource> source);