NHibernate清除/截断表并在单个事务

时间:2015-05-09 11:07:15

标签: .net nhibernate fluent-nhibernate

拥有一个没有关系的表和一个整数主键。使用NHibernate我想在单个事务中重新填充表,如下所示:

  • openTrans
  • 删除所有行
  • 插入新行(许多行将与之前删除的行具有相同的ID)
  • commitTrans

然而,NHibernate抛出了一个具有相同标识符值的不同对象已经与会话相关联'在我尝试保存新实体的地方。这是有道理的,因为我事实上创建了一个具有相同Id的新实体。我试图通过覆盖实体类上的GetHashCode和Equals来欺骗NHibernate,这样两个具有相同ID的对象就等于'但我得到了同样的结果。

我可以采取的另一种方法是更新已经存在的实体,删除不在新数据集中的现有实体并添加新实体,但这是我希望避免的大量工作,因为故事只是重新填充表。我当然可以在两个会话中执行此操作,但我希望整个操作都是原子操作。

1 个答案:

答案 0 :(得分:2)

选项1

session.Clear();  // to get rid associations of the objects in memory
session.CreateQuery("delete from MyClass").ExecuteUpdate();
foreach(var entity in CreateNew())
    session.Save(entity);

选项2

session.CreateQuery("delete from MyClass where Id not in (:ids)")
    .SetParameterList("ids", newIds)
    .ExecuteUpdate();
foreach (var id in newIds)
{
    var entity = session.Get<MyClass>(id); // returns the cached instance if present or the database instance or null if non existant
    if (entity == null)
    {
        entity = new MyClass { Id = id };
        session.Save(entity);
    }
    Populate(entity);
}

选项3

var newEntities = CreateNew();

session.CreateQuery("delete from MyClass where Id not in (:ids)")
    .SetParameterList("ids", newEntities.Select(x => x.Id).ToArray())
    .ExecuteUpdate();

foreach(var entity in newEntities)
    session.Merge(entity);  // will get the object with the same id and copies over properties over