NHibernate Purge/Truncate Table 并在单个事务中重新填充
NHibernate Purge/Truncate Table and repopulate in single transaction
有一个没有关系的 table 和一个整数主键。使用 NHibernate,我想在单个事务中重新填充 table,如下所示:
- openTrans
- 删除所有行
- 插入新行(许多将与之前删除的行具有相同的 ID)
- 提交交易
但是 NHibernate 在我尝试保存新实体时抛出 'a different object with the same identifier value was already associated with the session'。这是有道理的,因为我实际上已经创建了一个具有相同 ID 的新实体。我试图通过覆盖实体 class 上的 GetHashCode 和 Equals 来蒙蔽 NHibernate,这样具有相同 ID 的两个对象是 'equal',但我得到相同的结果。
我可以采取的另一种方法是更新已经存在的实体,删除不在新数据集中的现有实体并添加新实体,但这是我希望避免的很多工作,因为这个故事只是为了重新填充 table。我当然可以在两个会话中执行此操作,但我希望整个操作是原子的。
选项 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
有一个没有关系的 table 和一个整数主键。使用 NHibernate,我想在单个事务中重新填充 table,如下所示:
- openTrans
- 删除所有行
- 插入新行(许多将与之前删除的行具有相同的 ID)
- 提交交易
但是 NHibernate 在我尝试保存新实体时抛出 'a different object with the same identifier value was already associated with the session'。这是有道理的,因为我实际上已经创建了一个具有相同 ID 的新实体。我试图通过覆盖实体 class 上的 GetHashCode 和 Equals 来蒙蔽 NHibernate,这样具有相同 ID 的两个对象是 'equal',但我得到相同的结果。
我可以采取的另一种方法是更新已经存在的实体,删除不在新数据集中的现有实体并添加新实体,但这是我希望避免的很多工作,因为这个故事只是为了重新填充 table。我当然可以在两个会话中执行此操作,但我希望整个操作是原子的。
选项 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